From c41bf9603972362ee2936247d81b21d495081470 Mon Sep 17 00:00:00 2001 From: DianQK Date: Sat, 18 Nov 2023 20:01:01 +0800 Subject: [PATCH] Add thinlto support to codegen, assembly and coverage tests --- src/tools/compiletest/src/runtest.rs | 70 ++++++++++++++++++++++------ tests/assembly/thin-lto.rs | 8 ++++ tests/codegen/thin-lto.rs | 7 +++ tests/coverage/thin-lto.cov-map | 8 ++++ tests/coverage/thin-lto.coverage | 5 ++ tests/coverage/thin-lto.rs | 4 ++ 6 files changed, 87 insertions(+), 15 deletions(-) create mode 100644 tests/assembly/thin-lto.rs create mode 100644 tests/codegen/thin-lto.rs create mode 100644 tests/coverage/thin-lto.cov-map create mode 100644 tests/coverage/thin-lto.coverage create mode 100644 tests/coverage/thin-lto.rs diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 10a11e8e29188..af2243603193b 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -474,14 +474,12 @@ impl<'test> TestCx<'test> { self.fatal("missing --coverage-dump"); }; - let proc_res = self.compile_test_and_save_ir(); + let (proc_res, llvm_ir_path) = self.compile_test_and_save_ir(); if !proc_res.status.success() { self.fatal_proc_rec("compilation failed!", &proc_res); } drop(proc_res); - let llvm_ir_path = self.output_base_name().with_extension("ll"); - let mut dump_command = Command::new(coverage_dump_path); dump_command.arg(llvm_ir_path); let proc_res = self.run_command_to_procres(&mut dump_command); @@ -2785,10 +2783,54 @@ impl<'test> TestCx<'test> { proc_res.fatal(None, || on_failure(*self)); } + fn get_output_file(&self, extension: &str) -> TargetLocation { + let thin_lto = self.props.compile_flags.iter().any(|s| s.ends_with("lto=thin")); + if thin_lto { + TargetLocation::ThisDirectory(self.output_base_dir()) + } else { + // This works with both `--emit asm` (as default output name for the assembly) + // and `ptx-linker` because the latter can write output at requested location. + let output_path = self.output_base_name().with_extension(extension); + let output_file = TargetLocation::ThisFile(output_path.clone()); + output_file + } + } + + fn get_filecheck_file(&self, extension: &str) -> PathBuf { + let thin_lto = self.props.compile_flags.iter().any(|s| s.ends_with("lto=thin")); + if thin_lto { + let name = self.testpaths.file.file_stem().unwrap().to_str().unwrap(); + let canonical_name = name.replace('-', "_"); + let mut output_file = None; + for entry in self.output_base_dir().read_dir().unwrap() { + if let Ok(entry) = entry { + let entry_path = entry.path(); + let entry_file = entry_path.file_name().unwrap().to_str().unwrap(); + if entry_file.starts_with(&format!("{}.{}", name, canonical_name)) + && entry_file.ends_with(extension) + { + assert!( + output_file.is_none(), + "thinlto doesn't support multiple cgu tests" + ); + output_file = Some(entry_file.to_string()); + } + } + } + if let Some(output_file) = output_file { + self.output_base_dir().join(output_file) + } else { + self.output_base_name().with_extension(extension) + } + } else { + self.output_base_name().with_extension(extension) + } + } + // codegen tests (using FileCheck) - fn compile_test_and_save_ir(&self) -> ProcRes { - let output_file = TargetLocation::ThisDirectory(self.output_base_dir()); + fn compile_test_and_save_ir(&self) -> (ProcRes, PathBuf) { + let output_file = self.get_output_file("ll"); let input_file = &self.testpaths.file; let rustc = self.make_compile_args( input_file, @@ -2799,15 +2841,13 @@ impl<'test> TestCx<'test> { Vec::new(), ); - self.compose_and_run_compiler(rustc, None) + let proc_res = self.compose_and_run_compiler(rustc, None); + let output_path = self.get_filecheck_file("ll"); + (proc_res, output_path) } fn compile_test_and_save_assembly(&self) -> (ProcRes, PathBuf) { - // This works with both `--emit asm` (as default output name for the assembly) - // and `ptx-linker` because the latter can write output at requested location. - let output_path = self.output_base_name().with_extension("s"); - - let output_file = TargetLocation::ThisFile(output_path.clone()); + let output_file = self.get_output_file("s"); let input_file = &self.testpaths.file; let mut emit = Emit::None; @@ -2837,7 +2877,9 @@ impl<'test> TestCx<'test> { Vec::new(), ); - (self.compose_and_run_compiler(rustc, None), output_path) + let proc_res = self.compose_and_run_compiler(rustc, None); + let output_path = self.get_filecheck_file("s"); + (proc_res, output_path) } fn verify_with_filecheck(&self, output: &Path) -> ProcRes { @@ -2870,7 +2912,7 @@ impl<'test> TestCx<'test> { self.fatal("missing --llvm-filecheck"); } - let proc_res = self.compile_test_and_save_ir(); + let (proc_res, output_path) = self.compile_test_and_save_ir(); if !proc_res.status.success() { self.fatal_proc_rec("compilation failed!", &proc_res); } @@ -2878,8 +2920,6 @@ impl<'test> TestCx<'test> { if let Some(PassMode::Build) = self.pass_mode() { return; } - - let output_path = self.output_base_name().with_extension("ll"); let proc_res = self.verify_with_filecheck(&output_path); if !proc_res.status.success() { self.fatal_proc_rec("verification with 'FileCheck' failed", &proc_res); diff --git a/tests/assembly/thin-lto.rs b/tests/assembly/thin-lto.rs new file mode 100644 index 0000000000000..deb8fd21d14f0 --- /dev/null +++ b/tests/assembly/thin-lto.rs @@ -0,0 +1,8 @@ +// compile-flags: -O -C lto=thin -C prefer-dynamic=no +// only-x86_64-unknown-linux-gnu +// assembly-output: emit-asm + +// CHECK: main + +pub fn main() { +} diff --git a/tests/codegen/thin-lto.rs b/tests/codegen/thin-lto.rs new file mode 100644 index 0000000000000..7991cad7a0ca8 --- /dev/null +++ b/tests/codegen/thin-lto.rs @@ -0,0 +1,7 @@ +// compile-flags: -O -C lto=thin -C prefer-dynamic=no +// only-x86_64-unknown-linux-gnu + +// CHECK: main + +pub fn main() { +} diff --git a/tests/coverage/thin-lto.cov-map b/tests/coverage/thin-lto.cov-map new file mode 100644 index 0000000000000..7e84e398f8454 --- /dev/null +++ b/tests/coverage/thin-lto.cov-map @@ -0,0 +1,8 @@ +Function name: thin_lto::main +Raw bytes (9): 0x[01, 01, 00, 01, 01, 03, 01, 01, 02] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 0 +Number of file 0 mappings: 1 +- Code(Counter(0)) at (prev + 3, 1) to (start + 1, 2) + diff --git a/tests/coverage/thin-lto.coverage b/tests/coverage/thin-lto.coverage new file mode 100644 index 0000000000000..21abb5dce04e1 --- /dev/null +++ b/tests/coverage/thin-lto.coverage @@ -0,0 +1,5 @@ + LL| |// compile-flags: -O -C lto=thin -C prefer-dynamic=no + LL| | + LL| 1|pub fn main() { + LL| 1|} + diff --git a/tests/coverage/thin-lto.rs b/tests/coverage/thin-lto.rs new file mode 100644 index 0000000000000..050aac2631971 --- /dev/null +++ b/tests/coverage/thin-lto.rs @@ -0,0 +1,4 @@ +// compile-flags: -O -C lto=thin -C prefer-dynamic=no + +pub fn main() { +}