Skip to content

Commit 2243de0

Browse files
alexcrichtonnagisa
authored andcommitted
Force 1 CGU when release mode is enabled
We've locally started setting up OSS fuzz and Rust recently, but we're unfortunately getting a lot of timeouts where tests are taking much longer than expected. After some investigation one cause of the issue seems to be that although we're compiling the fuzzers in release mode they're still performing quite badly at runtime. One cause of this appears to be that functions are not being inlined across CGUs within a crate, and digging even further seems to show that functions are tagged with `notEligibleToImport` which presumably means that ThinLTO cannot import them across CGUs. Poking around in LLVM it looks like the sancov passes add mutations of a private `__sancov_gen_` global in all functions in a CGU, and then that global itself is listed as not importable. Any function referencing something not importable is then also considered not importable, hence nothing in any CGU is importable. With this change, however, the performance of optimized-Rust being sanitized is unfortunately still ~100x slower than non-sanitized Rust. I don't think the overhead is supposed to be that high so I'm still looking into other causes of slowness.
1 parent 1f54f01 commit 2243de0

File tree

1 file changed

+12
-0
lines changed

1 file changed

+12
-0
lines changed

src/project.rs

+12
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,18 @@ impl FuzzProject {
174174
rustflags.push_str(" -Cdebug-assertions");
175175
}
176176

177+
// If release mode is enabled then we force 1 CGU to be used in rustc.
178+
// This will result in slower compilations but it looks like the sancov
179+
// passes otherwise add `notEligibleToImport` annotations to functions
180+
// in LLVM IR, meaning that *nothing* can get imported with ThinLTO.
181+
// This means that in release mode, where ThinLTO is critical for
182+
// performance, we're taking a huge hit relative to actual release mode.
183+
// Local tests have once showed this to be a ~3x faster runtime where
184+
// otherwise functions like `Vec::as_ptr` aren't inlined.
185+
if build.release {
186+
rustflags.push_str(" -C codegen-units=1");
187+
}
188+
177189
if let Ok(other_flags) = env::var("RUSTFLAGS") {
178190
rustflags.push_str(" ");
179191
rustflags.push_str(&other_flags);

0 commit comments

Comments
 (0)