use std::fs;
use std::fs::File;
use std::io::Write;
use std::path::Path;
use std::time::SystemTime;
fn main() {
let n = 8096;
let group_size = 1024;
let generated_file = "src/generated_code.rs"; let build_script = "build.rs";
if Path::new(generated_file).exists() {
let generated_time = fs::metadata(generated_file)
.and_then(|metadata| metadata.modified())
.unwrap_or(SystemTime::UNIX_EPOCH);
let trigger_time = fs::metadata(build_script)
.and_then(|metadata| metadata.modified())
.unwrap_or(SystemTime::UNIX_EPOCH);
if trigger_time <= generated_time {
println!("Generated code is up-to-date.");
return;
}
}
let mut file = File::create(generated_file).unwrap();
writeln!(file, "use std::arch::asm;").unwrap();
writeln!(file, "use std::hint::black_box;").unwrap();
writeln!(
file,
"/// This function should not be inlined by the compiler to prevent the generated code from being optimized out"
)
.unwrap();
writeln!(file, "#[inline(never)]").unwrap();
writeln!(file, "pub fn do_something(val: u32) {{").unwrap();
writeln!(file, " black_box(val);").unwrap();
writeln!(file, "}}").unwrap();
let mut function_count = 0;
for chunk in (0..n).collect::<Vec<_>>().chunks(group_size) {
writeln!(file, "#[inline(never)]").unwrap();
writeln!(
file,
"pub fn eval_branches_{}(random: &mut dyn FnMut() -> u32) {{",
function_count
)
.unwrap();
for i in chunk {
writeln!(file, " let val = random();").unwrap();
writeln!(file, " if val % 2 == 1 {{").unwrap();
writeln!(file, " do_something(val);").unwrap();
writeln!(file, " }}").unwrap();
let nop_count = i % 4;
if nop_count != 0 {
writeln!(file, " unsafe {{").unwrap();
for _ in 0..nop_count {
writeln!(file, " asm!(\"nop\");").unwrap();
}
writeln!(file, " }}").unwrap();
}
}
writeln!(file, "}}").unwrap();
function_count += 1;
}
writeln!(file, "#[inline(never)]").unwrap();
writeln!(
file,
"pub fn eval_branches(random: &mut dyn FnMut() -> u32) {{"
)
.unwrap();
for i in 0..function_count {
writeln!(file, " eval_branches_{}(random);", i).unwrap();
}
writeln!(file, "}}").unwrap();
println!("cargo:rerun-if-changed={}", build_script);
}