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); - } -}