From 47cb8234b677fdb095337a2c5b8b1c4686bf58db Mon Sep 17 00:00:00 2001 From: Jamey Sharp Date: Wed, 3 Aug 2022 14:28:37 -0700 Subject: [PATCH] Remove old tests and reexport libfuzzer from fuzzing module (#69) * Remove unused regalloc2-test crate This code doesn't build, and Chris says it's "a really old harness that existed prior to building the fuzzing and was used mainly to profile and get stats before integration with Cranelift". * Re-export libfuzzer/arbitrary from fuzzing module This avoids needing to keep dependencies on `arbitrary` in sync across the three different Cargo.toml files in this project. However, before version 0.4.2, libfuzzer-sys only supported using its macros if it was available at the top-level `libfuzzer_sys` path, which breaks when re-exporting it. So I'm upgrading to that version (or the newest patch release of it). Upgrading libfuzzer-sys in turn brings in the 1.0 release of the arbitrary crate, with a minor API change along the way. --- Cargo.toml | 5 ++- fuzz/Cargo.toml | 2 -- fuzz/fuzz_targets/domtree.rs | 14 +++----- fuzz/fuzz_targets/ion.rs | 3 +- fuzz/fuzz_targets/ion_checker.rs | 7 ++-- fuzz/fuzz_targets/moves.rs | 7 ++-- fuzz/fuzz_targets/ssagen.rs | 7 ++-- src/fuzzing/func.rs | 8 ++--- src/fuzzing/mod.rs | 2 ++ test/Cargo.toml | 28 ---------------- test/benches/regalloc.rs | 56 -------------------------------- test/src/main.rs | 50 ---------------------------- 12 files changed, 23 insertions(+), 166 deletions(-) delete mode 100644 test/Cargo.toml delete mode 100644 test/benches/regalloc.rs delete mode 100644 test/src/main.rs diff --git a/Cargo.toml b/Cargo.toml index 7878a4d..4f0c0d6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,8 +20,7 @@ slice-group-by = "0.3.0" serde = { version = "1.0.136", features = ["derive"], optional = true } # The below are only needed for fuzzing. -# Keep this in sync with libfuzzer_sys's crate version: -arbitrary = { version = "^0.4.6", optional = true } +libfuzzer-sys = { version = "0.4.2", optional = true } # When testing regalloc2 by itself, enable debug assertions and overflow checks [profile.release] @@ -39,7 +38,7 @@ checker = [] trace-log = [] # Exposes the internal API for fuzzing. -fuzzing = ["arbitrary", "checker", "trace-log"] +fuzzing = ["libfuzzer-sys", "checker", "trace-log"] # Enables serde for exposed types. enable-serde = ["serde"] diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index 4bf4e17..1df5bd3 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -11,8 +11,6 @@ cargo-fuzz = true [dependencies] regalloc2 = { path = "../", features = ["fuzzing"] } -libfuzzer-sys = "0.3" -arbitrary = { version = "^0.4.6", features = ["derive"] } log = { version = "0.4.8", default-features = false } env_logger = "0.8.3" diff --git a/fuzz/fuzz_targets/domtree.rs b/fuzz/fuzz_targets/domtree.rs index c89b443..5957ccf 100644 --- a/fuzz/fuzz_targets/domtree.rs +++ b/fuzz/fuzz_targets/domtree.rs @@ -4,15 +4,11 @@ */ #![no_main] -use libfuzzer_sys::arbitrary::{Arbitrary, Result, Unstructured}; -use libfuzzer_sys::fuzz_target; +use regalloc2::fuzzing::arbitrary::{Arbitrary, Result, Unstructured}; +use regalloc2::fuzzing::{domtree, fuzz_target, postorder}; +use regalloc2::Block; use std::collections::HashSet; -use regalloc2::{ - fuzzing::{domtree, postorder}, - Block, -}; - #[derive(Clone, Debug)] struct CFG { num_blocks: usize, @@ -20,7 +16,7 @@ struct CFG { succs: Vec>, } -impl Arbitrary for CFG { +impl Arbitrary<'_> for CFG { fn arbitrary(u: &mut Unstructured) -> Result { let num_blocks = u.int_in_range(1..=1000)?; let mut succs = vec![]; @@ -111,7 +107,7 @@ struct TestCase { path: Path, } -impl Arbitrary for TestCase { +impl Arbitrary<'_> for TestCase { fn arbitrary(u: &mut Unstructured) -> Result { let cfg = CFG::arbitrary(u)?; let path = Path::choose_from_cfg(&cfg, u)?; diff --git a/fuzz/fuzz_targets/ion.rs b/fuzz/fuzz_targets/ion.rs index 485c36b..6d6e5be 100644 --- a/fuzz/fuzz_targets/ion.rs +++ b/fuzz/fuzz_targets/ion.rs @@ -4,9 +4,8 @@ */ #![no_main] -use libfuzzer_sys::fuzz_target; - use regalloc2::fuzzing::func::Func; +use regalloc2::fuzzing::fuzz_target; fuzz_target!(|func: Func| { let _ = env_logger::try_init(); diff --git a/fuzz/fuzz_targets/ion_checker.rs b/fuzz/fuzz_targets/ion_checker.rs index a5b7620..795d530 100644 --- a/fuzz/fuzz_targets/ion_checker.rs +++ b/fuzz/fuzz_targets/ion_checker.rs @@ -4,18 +4,17 @@ */ #![no_main] -use libfuzzer_sys::arbitrary::{Arbitrary, Result, Unstructured}; -use libfuzzer_sys::fuzz_target; - +use regalloc2::fuzzing::arbitrary::{Arbitrary, Result, Unstructured}; use regalloc2::fuzzing::checker::Checker; use regalloc2::fuzzing::func::{Func, Options}; +use regalloc2::fuzzing::fuzz_target; #[derive(Clone, Debug)] struct TestCase { func: Func, } -impl Arbitrary for TestCase { +impl Arbitrary<'_> for TestCase { fn arbitrary(u: &mut Unstructured) -> Result { Ok(TestCase { func: Func::arbitrary_with_options( diff --git a/fuzz/fuzz_targets/moves.rs b/fuzz/fuzz_targets/moves.rs index b150016..1971fec 100644 --- a/fuzz/fuzz_targets/moves.rs +++ b/fuzz/fuzz_targets/moves.rs @@ -4,9 +4,8 @@ */ #![no_main] -use libfuzzer_sys::arbitrary::{Arbitrary, Result, Unstructured}; -use libfuzzer_sys::fuzz_target; - +use regalloc2::fuzzing::arbitrary::{Arbitrary, Result, Unstructured}; +use regalloc2::fuzzing::fuzz_target; use regalloc2::fuzzing::moves::{MoveAndScratchResolver, ParallelMoves}; use regalloc2::{Allocation, PReg, RegClass, SpillSlot}; use std::collections::{HashMap, HashSet}; @@ -17,7 +16,7 @@ struct TestCase { available_pregs: Vec, } -impl Arbitrary for TestCase { +impl Arbitrary<'_> for TestCase { fn arbitrary(u: &mut Unstructured) -> Result { let mut ret = TestCase { moves: vec![], diff --git a/fuzz/fuzz_targets/ssagen.rs b/fuzz/fuzz_targets/ssagen.rs index bed2253..054275f 100644 --- a/fuzz/fuzz_targets/ssagen.rs +++ b/fuzz/fuzz_targets/ssagen.rs @@ -4,11 +4,10 @@ */ #![no_main] -use libfuzzer_sys::arbitrary::{Arbitrary, Result, Unstructured}; -use libfuzzer_sys::fuzz_target; - +use regalloc2::fuzzing::arbitrary::{Arbitrary, Result, Unstructured}; use regalloc2::fuzzing::cfg::CFGInfo; use regalloc2::fuzzing::func::{Func, Options}; +use regalloc2::fuzzing::fuzz_target; use regalloc2::fuzzing::ssa::validate_ssa; #[derive(Debug)] @@ -16,7 +15,7 @@ struct TestCase { f: Func, } -impl Arbitrary for TestCase { +impl Arbitrary<'_> for TestCase { fn arbitrary(u: &mut Unstructured) -> Result { Ok(TestCase { f: Func::arbitrary_with_options( diff --git a/src/fuzzing/func.rs b/src/fuzzing/func.rs index 47899d5..21754a0 100644 --- a/src/fuzzing/func.rs +++ b/src/fuzzing/func.rs @@ -8,8 +8,8 @@ use crate::{ OperandConstraint, OperandKind, OperandPos, PReg, PRegSet, RegClass, VReg, }; -use arbitrary::Result as ArbitraryResult; -use arbitrary::{Arbitrary, Unstructured}; +use super::arbitrary::Result as ArbitraryResult; +use super::arbitrary::{Arbitrary, Unstructured}; #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum InstOpcode { @@ -235,7 +235,7 @@ impl FuncBuilder { } } -impl Arbitrary for OperandConstraint { +impl Arbitrary<'_> for OperandConstraint { fn arbitrary(u: &mut Unstructured) -> ArbitraryResult { Ok(*u.choose(&[OperandConstraint::Any, OperandConstraint::Reg])?) } @@ -293,7 +293,7 @@ impl std::default::Default for Options { } } -impl Arbitrary for Func { +impl Arbitrary<'_> for Func { fn arbitrary(u: &mut Unstructured) -> ArbitraryResult { Func::arbitrary_with_options(u, &Options::default()) } diff --git a/src/fuzzing/mod.rs b/src/fuzzing/mod.rs index 1ab9d6d..69e0753 100644 --- a/src/fuzzing/mod.rs +++ b/src/fuzzing/mod.rs @@ -28,3 +28,5 @@ pub mod ion { pub mod checker { pub use crate::checker::*; } + +pub use libfuzzer_sys::{arbitrary, fuzz_target}; diff --git a/test/Cargo.toml b/test/Cargo.toml deleted file mode 100644 index bfbb291..0000000 --- a/test/Cargo.toml +++ /dev/null @@ -1,28 +0,0 @@ -[package] -name = "regalloc2-test" -version = "0.0.1" -authors = ["Chris Fallin ", "Mozilla SpiderMonkey Developers"] -edition = "2018" -license = "Apache-2.0 WITH LLVM-exception AND MPL-2.0" -description = "small test driver for benchmarking regalloc2" -repository = "https://github.com/bytecodealliance/regalloc2" - -[dependencies] -regalloc2 = { version = "*", path = "../", features = ["fuzzing"] } - -# Keep this in sync with libfuzzer_sys's crate version: -arbitrary = { version = "^0.4.6" } -rand = { version = "0.8" } -rand_chacha = { version = "0.3" } -env_logger = { version = "*" } - -[dev-dependencies] -criterion = "0.3" - -[profile.release] -debug = true - -[[bench]] -name = "regalloc" -harness = false - diff --git a/test/benches/regalloc.rs b/test/benches/regalloc.rs deleted file mode 100644 index 85cee8c..0000000 --- a/test/benches/regalloc.rs +++ /dev/null @@ -1,56 +0,0 @@ -//! Criterion-based benchmark target that computes insts/second for -//! arbitrary inputs. - -use arbitrary::{Arbitrary, Unstructured}; -use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Throughput}; -use rand::{Rng, SeedableRng}; -use rand_chacha::ChaCha8Rng; -use regalloc2::fuzzing::func::{machine_env, Func}; -use regalloc2::ion; -use regalloc2::Function; - -fn create_random_func(seed: u64, size: usize) -> Func { - let mut bytes: Vec = vec![]; - bytes.resize(size, 0); - let mut rng = ChaCha8Rng::seed_from_u64(seed); - rng.fill(&mut bytes[..]); - loop { - let mut u = Unstructured::new(&bytes[..]); - match Func::arbitrary(&mut u) { - Ok(f) => { - return f; - } - Err(arbitrary::Error::NotEnoughData) => { - let len = bytes.len(); - bytes.resize(len + 1024, 0); - rng.fill(&mut bytes[len..]); - } - Err(e) => panic!("unexpected error: {:?}", e), - } - } -} - -fn run_regalloc(c: &mut Criterion) { - const SIZE: usize = 1000 * 1000; - env_logger::init(); - let env = machine_env(); - let mut group = c.benchmark_group("benches"); - for iter in 0..3 { - let func = create_random_func(iter, SIZE); - eprintln!("==== {} instructions", func.insts()); - group.throughput(Throughput::Elements(func.insts() as u64)); - group.bench_with_input(BenchmarkId::from_parameter(iter), &iter, |b, _| { - b.iter(|| { - // For fair comparison with regalloc.rs, which needs - // to clone its Func on every alloc, we clone - // too. Seems to make a few percent difference. - let func = func.clone(); - ion::run(&func, &env).expect("regalloc did not succeed"); - }); - }); - } - group.finish(); -} - -criterion_group!(benches, run_regalloc); -criterion_main!(benches); diff --git a/test/src/main.rs b/test/src/main.rs deleted file mode 100644 index c6fd779..0000000 --- a/test/src/main.rs +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Released under the terms of the Apache 2.0 license with LLVM - * exception. See `LICENSE` for details. - */ - -use arbitrary::{Arbitrary, Unstructured}; -use rand::{Rng, SeedableRng}; -use rand_chacha::ChaCha8Rng; -use regalloc2::fuzzing::func::{machine_env, Func}; -use regalloc2::ion; -use regalloc2::Function; - -fn create_random_func(seed: u64, size: usize) -> Func { - let mut bytes: Vec = vec![]; - bytes.resize(size, 0); - let mut rng = ChaCha8Rng::seed_from_u64(seed); - rng.fill(&mut bytes[..]); - loop { - let mut u = Unstructured::new(&bytes[..]); - match Func::arbitrary(&mut u) { - Ok(f) => { - return f; - } - Err(arbitrary::Error::NotEnoughData) => { - let len = bytes.len(); - bytes.resize(len + 1024, 0); - rng.fill(&mut bytes[len..]); - } - Err(e) => panic!("unexpected error: {:?}", e), - } - } -} - -fn main() { - const SIZE: usize = 1000 * 1000; - env_logger::init(); - let env = machine_env(); - for iter in 0..3 { - let func = create_random_func(iter, SIZE); - eprintln!("==== {} instructions", func.insts()); - let mut stats: ion::Stats = ion::Stats::default(); - for i in 0..1000 { - let out = ion::run(&func, &env).expect("regalloc did not succeed"); - if i == 0 { - stats = out.stats; - } - } - eprintln!("Stats: {:?}", stats); - } -}