Skip to content

Commit 28e255c

Browse files
committed
intrinsic-test: simplify linker logic
just always compile .cpp to .o to maximize thread utilization, and only invoke the (maybe custom) linker at the very end
1 parent 2f92542 commit 28e255c

File tree

3 files changed

+52
-104
lines changed

3 files changed

+52
-104
lines changed

crates/intrinsic-test/src/arm/compile.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::common::cli::ProcessedCli;
22
use crate::common::compile_c::{CompilationCommandBuilder, CppCompilation};
33

4-
pub fn build_cpp_compilation(config: &ProcessedCli) -> Option<CppCompilation> {
4+
pub fn configure_cpp_compiler(config: &ProcessedCli) -> Option<CppCompilation> {
55
let cpp_compiler = config.cpp_compiler.as_ref()?;
66

77
// -ffp-contract=off emulates Rust's approach of not fusing separate mul-add operations

crates/intrinsic-test/src/arm/mod.rs

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -59,28 +59,34 @@ impl SupportedArchitectureTest for ArmArchitectureTest {
5959
let platform_headers = &["arm_neon.h", "arm_acle.h", "arm_fp16.h"];
6060

6161
let available_parallelism = std::thread::available_parallelism().unwrap().get();
62-
let chunk_size = self.intrinsics.len().div_ceil(available_parallelism);
62+
let chunk_count = Ord::min(available_parallelism, self.intrinsics.len());
63+
let chunk_size = self.intrinsics.len().div_ceil(chunk_count);
6364

64-
let pipeline = compile::build_cpp_compilation(&self.cli_options).unwrap();
65+
let cpp_compiler = compile::configure_cpp_compiler(&self.cli_options).unwrap();
6566

6667
let notice = &build_notices("// ");
6768
self.intrinsics
6869
.par_chunks(chunk_size)
6970
.enumerate()
7071
.map(|(i, chunk)| {
7172
let c_filename = format!("c_programs/mod_{i}.cpp");
73+
info!("writing {c_filename}");
7274
let mut file = File::create(&c_filename).unwrap();
7375
write_mod_cpp(&mut file, notice, c_target, platform_headers, chunk).unwrap();
7476

7577
// compile this cpp file into a .o file
76-
let output = pipeline.run(&[], &[format!("mod_{i}.cpp")], &format!("mod_{i}.o"))?;
78+
info!("compiling {c_filename}");
79+
let output = cpp_compiler
80+
.compile_object_file(&format!("mod_{i}.cpp"), &format!("mod_{i}.o"))?;
7781
assert!(output.status.success());
82+
info!("done compiling {c_filename}");
7883

7984
Ok(())
8085
})
8186
.collect::<Result<(), std::io::Error>>()
8287
.unwrap();
8388

89+
info!("writing main.cpp");
8490
let mut file = File::create("c_programs/main.cpp").unwrap();
8591
write_main_cpp(
8692
&mut file,
@@ -90,21 +96,35 @@ impl SupportedArchitectureTest for ArmArchitectureTest {
9096
)
9197
.unwrap();
9298

93-
// Files to include in the final link step.
94-
let mut includes = vec![];
95-
for i in 0..Ord::min(available_parallelism, self.intrinsics.len()) {
96-
includes.push(format!("mod_{i}.o"));
97-
}
98-
99-
let output = pipeline
100-
.run(
101-
&includes,
102-
&["main.cpp".to_string()],
103-
"intrinsic-test-programs",
104-
)
99+
// compile this cpp file into a .o file
100+
info!("compiling main.cpp");
101+
let output = cpp_compiler
102+
.compile_object_file("main.cpp", "intrinsic-test-programs.o")
105103
.unwrap();
106104
assert!(output.status.success());
107105

106+
let object_files = (0..chunk_count)
107+
.map(|i| format!("mod_{i}.o"))
108+
.chain(["intrinsic-test-programs.o".to_owned()]);
109+
110+
let output = match &self.cli_options.linker {
111+
Some(custom_linker) => {
112+
let mut linker = std::process::Command::new(custom_linker);
113+
114+
linker.current_dir("c_programs");
115+
116+
linker.args(object_files);
117+
linker.args(["-o", "intrinsic-test-programs"]);
118+
119+
info!("linking final C binary with {custom_linker}");
120+
linker.output()
121+
}
122+
None => cpp_compiler.link_executable(object_files, "intrinsic-test-programs"),
123+
};
124+
125+
let output = output.unwrap();
126+
assert!(output.status.success());
127+
108128
true
109129
}
110130

crates/intrinsic-test/src/common/compile_c.rs

Lines changed: 16 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -104,30 +104,19 @@ impl CompilationCommandBuilder {
104104
cpp_compiler.arg(format!("--target={target}"));
105105
}
106106

107-
if let (Some(linker), Some(cxx_toolchain_dir)) = (&self.linker, &self.cxx_toolchain_dir) {
107+
if let Some(cxx_toolchain_dir) = &self.cxx_toolchain_dir {
108108
cpp_compiler.args(
109109
self.include_paths
110110
.iter()
111-
.map(|path| "--include-directory=".to_string() + cxx_toolchain_dir + path),
111+
.map(|path| format!("--include-directory={cxx_toolchain_dir}{path}")),
112112
);
113-
114-
CppCompilation::CustomLinker {
115-
cpp_compiler,
116-
linker: linker.to_owned(),
117-
}
118-
} else {
119-
CppCompilation::Simple(cpp_compiler)
120113
}
114+
115+
CppCompilation(cpp_compiler)
121116
}
122117
}
123118

124-
pub enum CppCompilation {
125-
Simple(std::process::Command),
126-
CustomLinker {
127-
cpp_compiler: std::process::Command,
128-
linker: String,
129-
},
130-
}
119+
pub struct CppCompilation(std::process::Command);
131120

132121
fn clone_command(command: &std::process::Command) -> std::process::Command {
133122
let mut cmd = std::process::Command::new(command.get_program());
@@ -144,85 +133,24 @@ fn clone_command(command: &std::process::Command) -> std::process::Command {
144133
}
145134

146135
impl CppCompilation {
147-
fn compile_cpp(
148-
command: &std::process::Command,
149-
includes: &[String],
150-
inputs: &[String],
136+
pub fn compile_object_file(
137+
&self,
138+
input: &str,
151139
output: &str,
152140
) -> std::io::Result<std::process::Output> {
153-
let mut cmd = clone_command(command);
154-
cmd.args(includes);
155-
cmd.args(inputs);
156-
cmd.args(["-o", output]);
157-
158-
if output.ends_with(".o") {
159-
cmd.arg("-c");
160-
}
161-
141+
let mut cmd = clone_command(&self.0);
142+
cmd.args([input, "-c", "-o", output]);
162143
cmd.output()
163144
}
164145

165-
pub fn run(
146+
pub fn link_executable(
166147
&self,
167-
includes: &[String],
168-
inputs: &[String],
148+
inputs: impl Iterator<Item = String>,
169149
output: &str,
170150
) -> std::io::Result<std::process::Output> {
171-
match self {
172-
CppCompilation::Simple(command) => Self::compile_cpp(command, includes, inputs, output),
173-
CppCompilation::CustomLinker { cpp_compiler, .. } if output.ends_with(".o") => {
174-
// No need to invoke that custom linker if we're creating an object file.
175-
Self::compile_cpp(cpp_compiler, includes, inputs, output)
176-
}
177-
CppCompilation::CustomLinker {
178-
cpp_compiler,
179-
linker,
180-
} => {
181-
let object_file = &format!("{output}.o");
182-
183-
// Build an object file using the cpp compiler.
184-
let mut cmd = clone_command(cpp_compiler);
185-
cmd.args(inputs);
186-
cmd.args(["-c", "-o", object_file]);
187-
188-
let cpp_output = cmd.output()?;
189-
if !cpp_output.status.success() {
190-
error!("c++ compilaton failed");
191-
return Ok(cpp_output);
192-
}
193-
194-
trace!("using custom linker");
195-
196-
// Use the custom linker to turn the object file into an executable.
197-
let mut cmd = std::process::Command::new(linker);
198-
cmd.args(includes);
199-
cmd.args([object_file, "-o", output]);
200-
201-
if let Some(current_dir) = cpp_compiler.get_current_dir() {
202-
cmd.current_dir(current_dir);
203-
}
204-
205-
for (key, val) in cpp_compiler.get_envs() {
206-
cmd.env(key, val.unwrap_or_default());
207-
}
208-
209-
let linker_output = cmd.output()?;
210-
if !linker_output.status.success() {
211-
error!("custom linker failed");
212-
error!("{}", String::from_utf8_lossy(&linker_output.stderr));
213-
return Ok(linker_output);
214-
}
215-
216-
trace!("removing {object_file}");
217-
let object_file_path = match cpp_compiler.get_current_dir() {
218-
Some(current_dir) => &format!("{}/{object_file}", current_dir.display()),
219-
None => object_file,
220-
};
221-
222-
std::fs::remove_file(object_file_path)?;
223-
224-
Ok(cpp_output)
225-
}
226-
}
151+
let mut cmd = clone_command(&self.0);
152+
cmd.args(inputs);
153+
cmd.args(["-o", output]);
154+
cmd.output()
227155
}
228156
}

0 commit comments

Comments
 (0)