]>
Commit | Line | Data |
---|---|---|
fc512014 | 1 | #!/bin/bash |
923072b8 | 2 | # ignore-tidy-linelength |
fc512014 XL |
3 | |
4 | set -euxo pipefail | |
5 | ||
064997fb FG |
6 | ci_dir=`cd $(dirname $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 | ||
5e7ed085 | 44 | # Compile several crates to gather execution PGO profiles. |
04454e1e FG |
45 | # Arg0 => profiles (Debug, Opt) |
46 | # Arg1 => scenarios (Full, IncrFull, All) | |
5e7ed085 FG |
47 | # Arg2 => crates (syn, cargo, ...) |
48 | gather_profiles () { | |
064997fb | 49 | cd $BUILD_ROOT |
5e7ed085 FG |
50 | |
51 | # Compile libcore, both in opt-level=0 and opt-level=3 | |
064997fb FG |
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 | |
5e7ed085 | 58 | |
064997fb | 59 | cd $RUSTC_PERF |
5e7ed085 FG |
60 | |
61 | # Run rustc-perf benchmarks | |
62 | # Benchmark using profile_local with eprintln, which essentially just means | |
63 | # don't actually benchmark -- just make sure we run rustc a bunch of times. | |
64 | RUST_LOG=collector=debug \ | |
064997fb | 65 | RUSTC=$RUSTC_STAGE_0 \ |
5e7ed085 | 66 | RUSTC_BOOTSTRAP=1 \ |
064997fb FG |
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 | |
5e7ed085 FG |
78 | } |
79 | ||
923072b8 | 80 | # This path has to be absolute |
064997fb | 81 | LLVM_PROFILE_DIRECTORY_ROOT=$PGO_TMP/llvm-pgo |
923072b8 | 82 | |
3c0e092e XL |
83 | # We collect LLVM profiling information and rustc profiling information in |
84 | # separate phases. This increases build time -- though not by a huge amount -- | |
85 | # but prevents any problems from arising due to different profiling runtimes | |
86 | # being simultaneously linked in. | |
923072b8 FG |
87 | # LLVM IR PGO does not respect LLVM_PROFILE_FILE, so we have to set the profiling file |
88 | # path through our custom environment variable. We include the PID in the directory path | |
89 | # to avoid updates to profile files being lost because of race conditions. | |
064997fb | 90 | LLVM_PROFILE_DIR=${LLVM_PROFILE_DIRECTORY_ROOT}/prof-%p python3 $CHECKOUT/x.py build \ |
923072b8 FG |
91 | --target=$PGO_HOST \ |
92 | --host=$PGO_HOST \ | |
94222f64 | 93 | --stage 2 library/std \ |
94222f64 | 94 | --llvm-profile-generate |
fc512014 | 95 | |
064997fb FG |
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): $RUSTC_PERF | |
102 | else | |
103 | # rustc-perf version from 2022-07-22 | |
104 | PERF_COMMIT=3c253134664fdcba862c539d37f0de18557a9a4c | |
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 \ | |
5e7ed085 | 117 | RUSTC_BOOTSTRAP=1 \ |
064997fb | 118 | $CARGO_STAGE_0 build -p collector |
5e7ed085 | 119 | |
04454e1e FG |
120 | # Here we're profiling LLVM, so we only care about `Debug` and `Opt`, because we want to stress |
121 | # codegen. We also profile some of the most prolific crates. | |
122 | gather_profiles "Debug,Opt" "Full" \ | |
064997fb | 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" |
5e7ed085 | 124 | |
064997fb | 125 | LLVM_PROFILE_MERGED_FILE=$PGO_TMP/llvm-pgo.profdata |
923072b8 | 126 | |
3c0e092e XL |
127 | # Merge the profile data we gathered for LLVM |
128 | # Note that this uses the profdata from the clang we used to build LLVM, | |
129 | # which likely has a different version than our in-tree clang. | |
064997fb | 130 | $DOWNLOADED_LLVM/bin/llvm-profdata merge -o ${LLVM_PROFILE_MERGED_FILE} ${LLVM_PROFILE_DIRECTORY_ROOT} |
923072b8 FG |
131 | |
132 | echo "LLVM PGO statistics" | |
133 | du -sh ${LLVM_PROFILE_MERGED_FILE} | |
134 | du -sh ${LLVM_PROFILE_DIRECTORY_ROOT} | |
135 | echo "Profile file count" | |
136 | find ${LLVM_PROFILE_DIRECTORY_ROOT} -type f | wc -l | |
3c0e092e | 137 | |
064997fb FG |
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 | ||
3c0e092e XL |
141 | # Rustbuild currently doesn't support rebuilding LLVM when PGO options |
142 | # change (or any other llvm-related options); so just clear out the relevant | |
143 | # directories ourselves. | |
064997fb | 144 | rm -r $BUILD_ARTIFACTS/llvm $BUILD_ARTIFACTS/lld |
3c0e092e XL |
145 | |
146 | # Okay, LLVM profiling is done, switch to rustc PGO. | |
147 | ||
923072b8 | 148 | # The path has to be absolute |
064997fb | 149 | RUSTC_PROFILE_DIRECTORY_ROOT=$PGO_TMP/rustc-pgo |
923072b8 | 150 | |
064997fb | 151 | python3 $CHECKOUT/x.py build --target=$PGO_HOST --host=$PGO_HOST \ |
3c0e092e | 152 | --stage 2 library/std \ |
923072b8 | 153 | --rust-profile-generate=${RUSTC_PROFILE_DIRECTORY_ROOT} |
3c0e092e | 154 | |
04454e1e FG |
155 | # Here we're profiling the `rustc` frontend, so we also include `Check`. |
156 | # The benchmark set includes various stress tests that put the frontend under pressure. | |
064997fb FG |
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 | |
fc512014 XL |
174 | |
175 | # Merge the profile data we gathered | |
064997fb | 176 | $BUILD_ARTIFACTS/llvm/bin/llvm-profdata \ |
923072b8 FG |
177 | merge -o ${RUSTC_PROFILE_MERGED_FILE} ${RUSTC_PROFILE_DIRECTORY_ROOT} |
178 | ||
179 | echo "Rustc PGO statistics" | |
180 | du -sh ${RUSTC_PROFILE_MERGED_FILE} | |
181 | du -sh ${RUSTC_PROFILE_DIRECTORY_ROOT} | |
182 | echo "Profile file count" | |
183 | find ${RUSTC_PROFILE_DIRECTORY_ROOT} -type f | wc -l | |
fc512014 | 184 | |
064997fb FG |
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 | ||
94222f64 XL |
188 | # Rustbuild currently doesn't support rebuilding LLVM when PGO options |
189 | # change (or any other llvm-related options); so just clear out the relevant | |
190 | # directories ourselves. | |
064997fb | 191 | rm -r $BUILD_ARTIFACTS/llvm $BUILD_ARTIFACTS/lld |
94222f64 | 192 | |
2b03887a FG |
193 | if isLinux; then |
194 | # Gather BOLT profile (BOLT is currently only available on Linux) | |
195 | python3 ../x.py build --target=$PGO_HOST --host=$PGO_HOST \ | |
196 | --stage 2 library/std \ | |
197 | --llvm-profile-use=${LLVM_PROFILE_MERGED_FILE} \ | |
198 | --llvm-bolt-profile-generate | |
199 | ||
200 | BOLT_PROFILE_MERGED_FILE=/tmp/bolt.profdata | |
201 | ||
202 | # Here we're profiling Bolt. | |
203 | gather_profiles "Check,Debug,Opt" "Full" \ | |
204 | "syn-1.0.89,serde-1.0.136,ripgrep-13.0.0,regex-1.5.5,clap-3.1.6,hyper-0.14.18" | |
205 | ||
206 | merge-fdata /tmp/prof.fdata* > ${BOLT_PROFILE_MERGED_FILE} | |
207 | ||
208 | echo "BOLT statistics" | |
209 | du -sh /tmp/prof.fdata* | |
210 | du -sh ${BOLT_PROFILE_MERGED_FILE} | |
211 | echo "Profile file count" | |
212 | find /tmp/prof.fdata* -type f | wc -l | |
213 | ||
214 | rm -r $BUILD_ARTIFACTS/llvm $BUILD_ARTIFACTS/lld | |
215 | ||
216 | # This produces the actual final set of artifacts, using both the LLVM and rustc | |
217 | # collected profiling data. | |
218 | $@ \ | |
219 | --rust-profile-use=${RUSTC_PROFILE_MERGED_FILE} \ | |
220 | --llvm-profile-use=${LLVM_PROFILE_MERGED_FILE} \ | |
221 | --llvm-bolt-profile-use=${BOLT_PROFILE_MERGED_FILE} | |
222 | else | |
223 | $@ \ | |
224 | --rust-profile-use=${RUSTC_PROFILE_MERGED_FILE} \ | |
225 | --llvm-profile-use=${LLVM_PROFILE_MERGED_FILE} | |
226 | fi | |
064997fb FG |
227 | |
228 | echo "Rustc binary size" | |
229 | ls -la ./build/$PGO_HOST/stage2/bin | |
230 | ls -la ./build/$PGO_HOST/stage2/lib |