Skip to content

Commit 65598e9

Browse files
committed
wire up the writer into more of the rust emission code
1 parent 2f7b0a6 commit 65598e9

File tree

4 files changed

+83
-102
lines changed

4 files changed

+83
-102
lines changed

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

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -142,21 +142,25 @@ where
142142

143143
/// Creates a line for each argument that initializes an array for Rust from which `loads` argument
144144
/// values can be loaded as a sliding window, e.g `const A_VALS: [u32; 20] = [...];`
145-
pub fn gen_arglists_rust(&self, indentation: Indentation, loads: u32) -> String {
146-
self.iter()
147-
.filter(|&arg| !arg.has_constraint())
148-
.map(|arg| {
149-
format!(
150-
"{indentation}{bind} {name}: [{ty}; {load_size}] = {values};",
151-
bind = arg.rust_vals_array_binding(),
152-
name = arg.rust_vals_array_name(),
153-
ty = arg.ty.rust_scalar_type(),
154-
load_size = arg.ty.num_lanes() * arg.ty.num_vectors() + loads - 1,
155-
values = arg.ty.populate_random(indentation, loads, &Language::Rust)
156-
)
157-
})
158-
.collect::<Vec<_>>()
159-
.join("\n")
145+
pub fn gen_arglists_rust(
146+
&self,
147+
w: &mut impl std::io::Write,
148+
indentation: Indentation,
149+
loads: u32,
150+
) -> std::io::Result<()> {
151+
for arg in self.iter().filter(|&arg| !arg.has_constraint()) {
152+
writeln!(
153+
w,
154+
"{indentation}{bind} {name}: [{ty}; {load_size}] = {values};",
155+
bind = arg.rust_vals_array_binding(),
156+
name = arg.rust_vals_array_name(),
157+
ty = arg.ty.rust_scalar_type(),
158+
load_size = arg.ty.num_lanes() * arg.ty.num_vectors() + loads - 1,
159+
values = arg.ty.populate_random(indentation, loads, &Language::Rust)
160+
)?
161+
}
162+
163+
Ok(())
160164
}
161165

162166
/// Creates a line for each argument that initializes the argument from an array `[arg]_vals` at

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

Lines changed: 62 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -10,31 +10,6 @@ use super::intrinsic_helpers::IntrinsicTypeDefinition;
1010
// The number of times each intrinsic will be called.
1111
const PASSES: u32 = 20;
1212

13-
pub fn format_rust_main_template(
14-
notices: &str,
15-
definitions: &str,
16-
configurations: &str,
17-
arch_definition: &str,
18-
arglists: &str,
19-
passes: &str,
20-
) -> String {
21-
format!(
22-
r#"{notices}#![feature(simd_ffi)]
23-
#![feature(f16)]
24-
#![allow(unused)]
25-
{configurations}
26-
{definitions}
27-
28-
use core_arch::arch::{arch_definition}::*;
29-
30-
fn main() {{
31-
{arglists}
32-
{passes}
33-
}}
34-
"#,
35-
)
36-
}
37-
3813
fn write_cargo_toml(w: &mut impl std::io::Write, binaries: &[String]) -> std::io::Result<()> {
3914
writeln!(
4015
w,
@@ -123,11 +98,12 @@ pub fn compile_rust_programs(
12398
}
12499

125100
pub fn generate_rust_test_loop<T: IntrinsicTypeDefinition>(
101+
w: &mut impl std::io::Write,
126102
intrinsic: &dyn IntrinsicDefinition<T>,
127103
indentation: Indentation,
128104
additional: &str,
129105
passes: u32,
130-
) -> String {
106+
) -> std::io::Result<()> {
131107
let constraints = intrinsic.arguments().as_constraint_parameters_rust();
132108
let constraints = if !constraints.is_empty() {
133109
format!("::<{constraints}>")
@@ -138,7 +114,8 @@ pub fn generate_rust_test_loop<T: IntrinsicTypeDefinition>(
138114
let return_value = format_f16_return_value(intrinsic);
139115
let indentation2 = indentation.nested();
140116
let indentation3 = indentation2.nested();
141-
format!(
117+
write!(
118+
w,
142119
"{indentation}for i in 0..{passes} {{\n\
143120
{indentation2}unsafe {{\n\
144121
{loaded_args}\
@@ -153,74 +130,77 @@ pub fn generate_rust_test_loop<T: IntrinsicTypeDefinition>(
153130
)
154131
}
155132

156-
pub fn generate_rust_constraint_blocks<T: IntrinsicTypeDefinition>(
133+
fn generate_rust_constraint_blocks<'a, T: IntrinsicTypeDefinition + 'a>(
134+
w: &mut impl std::io::Write,
157135
intrinsic: &dyn IntrinsicDefinition<T>,
158136
indentation: Indentation,
159-
constraints: &[&Argument<T>],
137+
constraints: &mut (impl Iterator<Item = &'a Argument<T>> + Clone),
160138
name: String,
161-
) -> String {
162-
if let Some((current, constraints)) = constraints.split_last() {
163-
let range = current
164-
.constraint
165-
.iter()
166-
.map(|c| c.to_range())
167-
.flat_map(|r| r.into_iter());
168-
169-
let body_indentation = indentation.nested();
170-
range
171-
.map(|i| {
172-
format!(
173-
"{indentation}{{\n\
174-
{body_indentation}const {name}: {ty} = {val};\n\
175-
{pass}\n\
176-
{indentation}}}",
177-
name = current.name,
178-
ty = current.ty.rust_type(),
179-
val = i,
180-
pass = generate_rust_constraint_blocks(
181-
intrinsic,
182-
body_indentation,
183-
constraints,
184-
format!("{name}-{i}")
185-
)
186-
)
187-
})
188-
.join("\n")
189-
} else {
190-
generate_rust_test_loop(intrinsic, indentation, &name, PASSES)
139+
) -> std::io::Result<()> {
140+
let Some(current) = constraints.next() else {
141+
return generate_rust_test_loop(w, intrinsic, indentation, &name, PASSES);
142+
};
143+
144+
let body_indentation = indentation.nested();
145+
for i in current.constraint.iter().flat_map(|c| c.to_range()) {
146+
let ty = current.ty.rust_type();
147+
148+
writeln!(w, "{indentation}{{")?;
149+
150+
writeln!(w, "{body_indentation}const {}: {ty} = {i};", current.name)?;
151+
152+
generate_rust_constraint_blocks(
153+
w,
154+
intrinsic,
155+
body_indentation,
156+
&mut constraints.clone(),
157+
format!("{name}-{i}"),
158+
)?;
159+
160+
writeln!(w, "{indentation}}}")?;
191161
}
162+
163+
Ok(())
192164
}
193165

194166
// Top-level function to create complete test program
195167
pub fn create_rust_test_program<T: IntrinsicTypeDefinition>(
168+
w: &mut impl std::io::Write,
196169
intrinsic: &dyn IntrinsicDefinition<T>,
197170
target: &str,
198171
notice: &str,
199172
definitions: &str,
200173
cfg: &str,
201-
) -> String {
174+
) -> std::io::Result<()> {
175+
let indentation = Indentation::default();
176+
177+
write!(w, "{notice}")?;
178+
179+
writeln!(w, "#![feature(simd_ffi)]")?;
180+
writeln!(w, "#![feature(f16)]")?;
181+
writeln!(w, "#![allow(unused)]")?;
182+
183+
writeln!(w, "{cfg}")?;
184+
writeln!(w, "{definitions}")?;
185+
186+
writeln!(w, "use core_arch::arch::{target}::*;")?;
187+
188+
writeln!(w, "fn main() {{")?;
189+
190+
// Define the arrays of arguments.
202191
let arguments = intrinsic.arguments();
203-
let constraints = arguments
204-
.iter()
205-
.filter(|i| i.has_constraint())
206-
.collect_vec();
192+
arguments.gen_arglists_rust(w, indentation.nested(), PASSES)?;
207193

208-
let indentation = Indentation::default();
209-
format_rust_main_template(
210-
notice,
211-
definitions,
212-
cfg,
213-
target,
214-
intrinsic
215-
.arguments()
216-
.gen_arglists_rust(indentation.nested(), PASSES)
217-
.as_str(),
218-
generate_rust_constraint_blocks(
219-
intrinsic,
220-
indentation.nested(),
221-
&constraints,
222-
Default::default(),
223-
)
224-
.as_str(),
225-
)
194+
// Define any const generics as `const` items, then generate the actual test loop.
195+
generate_rust_constraint_blocks(
196+
w,
197+
intrinsic,
198+
indentation.nested(),
199+
&mut arguments.iter().rev().filter(|i| i.has_constraint()),
200+
Default::default(),
201+
)?;
202+
203+
writeln!(w, "}}")?;
204+
205+
Ok(())
226206
}

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,7 @@ where
6363
let rust_filename = format!("{rust_dir}/main.rs");
6464
let mut file = File::create(rust_filename).unwrap();
6565

66-
let rust_code =
67-
create_rust_test_program(intrinsic, rust_target, notice, definitions, cfg);
68-
69-
file.write_all(rust_code.as_bytes())?;
66+
create_rust_test_program(&mut file, intrinsic, rust_target, notice, definitions, cfg)?;
7067

7168
Ok(identifier)
7269
})

crates/intrinsic-test/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ fn main() {
3838
if !test_environment.build_rust_file() {
3939
std::process::exit(3);
4040
}
41-
info!("comaparing outputs");
41+
info!("comparing outputs");
4242
if !test_environment.compare_outputs() {
4343
std::process::exit(1);
4444
}

0 commit comments

Comments
 (0)