diff --git a/collector/src/main.rs b/collector/src/main.rs index 0893c85..85ecb7e 100644 --- a/collector/src/main.rs +++ b/collector/src/main.rs @@ -16,12 +16,13 @@ use compile_time::{ }, discover_benchmark_suit, }; +use mir_analyze::mir_generate::generate_mir; use runtime::bench_runtime; use toolchain::{Cli, Commands, ResultWriter}; use crate::{ - compile_time::binary_size::bench_binary_size, csv_transfer::sheduler, - morpheme_miner::run_miners, perf_analyze::perf_analyzer, + benchmark::benchmark::BenchmarkSuit, compile_time::binary_size::bench_binary_size, + csv_transfer::sheduler, morpheme_miner::run_miners, perf_analyze::perf_analyzer, statistics::compile_time_stat::CompileTimeResultSet, toolchain::get_local_toolchain, }; @@ -232,20 +233,8 @@ fn main_result() -> anyhow::Result { run_miners(bench_dir, out_path); Ok(0) } - Commands::MirAnalyze { - local, - bench_dir, - out_dir, - } => { - let toolch = get_local_toolchain( - &local.rustc, - local.cargo.as_deref(), - local.id.as_deref(), - "", - )?; - - mir_analyze::mir_analyze::entry(toolch, bench_dir, out_dir)?; - + Commands::MirAnalyze { mir_dir, out_path } => { + mir_analyze::mir_analyze::entry(mir_dir, out_path)?; Ok(0) } Commands::BinaryLocal { @@ -300,16 +289,21 @@ fn main_result() -> anyhow::Result { bench_dir, out_dir, } => { - let toolch = get_local_toolchain( + let ltc = get_local_toolchain( &local.rustc, local.cargo.as_deref(), local.id.as_deref(), "", )?; - discover_benchmark_suit(&bench_dir)? - .into_iter() - .for_each(|b| unimplemented!()); + let benchmark_suit = BenchmarkSuit { + benchmarks: discover_benchmark_suit(&bench_dir)?, + }; + println!("{}", benchmark_suit.display_benchmarks()); + + for b in benchmark_suit.benchmarks { + generate_mir(&b, <c, out_dir.as_path())?; + } Ok(0) } diff --git a/collector/src/mir_analyze/analyze/count.rs b/collector/src/mir_analyze/analyze/count.rs deleted file mode 100644 index d2c4421..0000000 --- a/collector/src/mir_analyze/analyze/count.rs +++ /dev/null @@ -1,68 +0,0 @@ -use std::collections::HashMap; - -use crate::mir_analyze::mirs::mir::{MIR, MOVE_TYPE, REF_TYPE}; - -pub type MirCount = HashMap; - -pub fn count_mir(mirs: &Vec) -> anyhow::Result { - let mut mir_number = MIR::get_all_types() - .into_iter() - .map(|s| (s, 0)) - .collect::>(); - - mirs.iter().for_each(|mir| { - *mir_number.get_mut(&mir.get_type()).unwrap() += 1; - - match mir { - MIR::CALL(c) => c.params.iter().for_each(|param| match param { - crate::mir_analyze::mirs::mir::Param::MOVE(_) => { - *mir_number.get_mut(&MOVE_TYPE.to_string()).unwrap() += 1 - } - _ => (), - }), - MIR::FIELDACCESS(f) => match f { - crate::mir_analyze::mirs::mir::FIELDACCESS::MOVE(_) => { - *mir_number.get_mut(&MOVE_TYPE.to_string()).unwrap() += 1 - } - crate::mir_analyze::mirs::mir::FIELDACCESS::REF(_) - | crate::mir_analyze::mirs::mir::FIELDACCESS::REFMUT(_) => { - *mir_number.get_mut(&REF_TYPE.to_string()).unwrap() += 1 - } - }, - _ => (), - }; - }); - - Ok(mir_number) -} - -#[cfg(test)] -mod test { - use std::path::PathBuf; - - use crate::mir_analyze::{ - analyze::reader::read_mir, - mirs::mir::{ASSIGN_TYPE, CALL_TYPE, FIELD_ACCESS_TYPE, MOVE_TYPE, REF_TYPE}, - }; - - use super::count_mir; - - #[test] - fn test_count_mir() { - let mir_file = PathBuf::from("test/mir_analyze/count/condvar-83823257d08c42e7.mir"); - - let numbers = count_mir(&read_mir(mir_file).unwrap()).unwrap(); - - let std_numbers = vec![ - (ASSIGN_TYPE.to_string(), 23u32), - (MOVE_TYPE.to_string(), 43), - (CALL_TYPE.to_string(), 24), - (FIELD_ACCESS_TYPE.to_string(), 3), - (REF_TYPE.to_string(), 18), - ] - .into_iter() - .collect(); - - assert_eq!(numbers, std_numbers); - } -} diff --git a/collector/src/mir_analyze/analyze/mod.rs b/collector/src/mir_analyze/analyze/mod.rs deleted file mode 100644 index 435f907..0000000 --- a/collector/src/mir_analyze/analyze/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod count; -pub mod reader; diff --git a/collector/src/mir_analyze/analyze/reader.rs b/collector/src/mir_analyze/analyze/reader.rs deleted file mode 100644 index d745f82..0000000 --- a/collector/src/mir_analyze/analyze/reader.rs +++ /dev/null @@ -1,781 +0,0 @@ -use std::{ - fs::File, - io::{BufRead, BufReader}, - path::PathBuf, -}; - -use crate::mir_analyze::mirs::mir::MIR; - -/// `read_mir` will take a mir file as input, -/// count the mir lines and classify the mirs into: -/// -/// * type bounding `let _i = some_type` -/// * assignment `_i = _j` or `_i = cosnt xxx` -/// * move `_i = move _j` -/// * ref `_i = &_j` or `_i = &mut _j` -/// * type-cast `_i = _j as xxx` -/// * function/method call `_i = domain/type_ascription::func(args) -> [return: bb_x, unwind: bb_y] | return bb_x`, e.g. _5 = > as Deref>::deref(move _6) -/// * switch `_i = discriminant(_j); switchInt(move _i) -> [blocks]` -/// * field access `_i = move (_j.x type) | &mut (_j.x type)| &(_j.x type)` -pub fn read_mir(path: PathBuf) -> anyhow::Result> { - let mut mirs = vec![]; - let file = File::open(path)?; - - let mut reader = BufReader::new(file); - - let mut buf = String::new(); - while reader.read_line(&mut buf)? > 0 { - if let Some(mir) = MIR::new(&buf) { - mirs.push(mir); - } - - buf.clear(); - } - - Ok(mirs) -} - -#[cfg(test)] -mod test { - - use super::MIR; - use crate::mir_analyze::mirs::mir::{ - Assign, Call, Const, FieldAccess, Move, Param, Reference, Value, Value::VAR, Var, - FIELDACCESS, - }; - - impl PartialEq for MIR { - fn eq(&self, other: &Self) -> bool { - match self { - MIR::ASSIGN(assign) => match other { - MIR::ASSIGN(o_assign) => assign == o_assign, - _ => false, - }, - MIR::MOVE(mv) => match other { - MIR::MOVE(o_move) => mv == o_move, - _ => false, - }, - MIR::CALL(call) => match other { - MIR::CALL(o_call) => call == o_call, - _ => false, - }, - MIR::REF(reference) => match other { - MIR::REF(o_ref) => reference == o_ref, - _ => false, - }, - MIR::FIELDACCESS(field_access) => match other { - MIR::FIELDACCESS(o_field_access) => field_access == o_field_access, - _ => false, - }, - } - } - } - - impl PartialEq for Assign { - fn eq(&self, other: &Self) -> bool { - self.left == other.left - } - } - - impl PartialEq for FIELDACCESS { - fn eq(&self, other: &Self) -> bool { - match self { - FIELDACCESS::MOVE(m) => match other { - FIELDACCESS::MOVE(o_m) => m == o_m, - _ => false, - }, - FIELDACCESS::REF(r) => match other { - FIELDACCESS::REF(o_r) => r == o_r, - _ => false, - }, - FIELDACCESS::REFMUT(r) => match other { - FIELDACCESS::REFMUT(o_r) => r == o_r, - _ => false, - }, - } - } - } - - impl PartialEq for FieldAccess { - fn eq(&self, other: &Self) -> bool { - self.left == other.left - && self.struct_var == other.struct_var - && self.field_num == other.field_num - } - } - - impl PartialEq for Reference { - fn eq(&self, other: &Self) -> bool { - self.src == other.src && self.dst == other.dst - } - } - - impl PartialEq for Call { - fn eq(&self, other: &Self) -> bool { - self.ret == other.ret - && self.label == other.label - && self.params == other.params - && self.next_block == other.next_block - && self.unwind_block == other.unwind_block - } - } - - impl PartialEq for Move { - fn eq(&self, other: &Self) -> bool { - self.left == other.left && self.right == other.right - } - } - - impl PartialEq for Param { - fn eq(&self, other: &Self) -> bool { - match self { - Param::MOVE(m) => match other { - Param::MOVE(o) => m == o, - _ => false, - }, - Param::VAR(v) => match other { - Param::VAR(o) => v == o, - _ => false, - }, - Param::COSNT(c) => match other { - Param::COSNT(o) => c == o, - _ => false, - }, - } - } - } - - impl PartialEq for Value { - fn eq(&self, other: &Self) -> bool { - match self { - Value::CONST(c) => match other { - Value::CONST(o_c) => c == o_c, - VAR(_) => false, - }, - VAR(v) => match other { - Value::CONST(_) => false, - VAR(o_v) => v == o_v, - }, - } - } - } - - impl PartialEq for Const { - fn eq(&self, other: &Self) -> bool { - self.val == other.val - } - } - - impl PartialEq for Var { - fn eq(&self, other: &Self) -> bool { - self.id == other.id - } - } - - #[test] - fn test_read_mir_condvar() { - use super::MIR::{ASSIGN, CALL, MOVE, REF}; - use crate::mir_analyze::mirs::mir::{ - Assign, Call, Const, Move, Param, Value, Value::VAR, Var, - }; - - use crate::mir_analyze::analyze::reader::read_mir; - use std::path::PathBuf; - - let mir_file = PathBuf::from("test/mir_analyze/reader/condvar-9b2e97b194975c57.mir"); - - let results = read_mir(mir_file).unwrap(); - - let std_results = vec![ - ASSIGN(Assign { - left: VAR(Var { id: 49 }), - right: Value::CONST(Const { - val: "false".to_string(), - }), - }), - ASSIGN(Assign { - left: VAR(Var { id: 50 }), - right: Value::CONST(Const { - val: "false".to_string(), - }), - }), - ASSIGN(Assign { - left: VAR(Var { id: 50 }), - right: Value::CONST(Const { - val: "true".to_string(), - }), - }), - ASSIGN(Assign { - left: VAR(Var { id: 50 }), - right: Value::CONST(Const { - val: "false".to_string(), - }), - }), - ASSIGN(Assign { - left: VAR(Var { id: 49 }), - right: Value::CONST(Const { - val: "true".to_string(), - }), - }), - ASSIGN(Assign { - left: VAR(Var { id: 11 }), - right: Value::CONST(Const { - val: "0_i32".to_string(), - }), - }), - ASSIGN(Assign { - left: VAR(Var { id: 18 }), - right: VAR(Var { id: 19 }), - }), - ASSIGN(Assign { - left: VAR(Var { id: 23 }), - right: VAR(Var { id: 11 }), - }), - ASSIGN(Assign { - left: VAR(Var { id: 49 }), - right: Value::CONST(Const { - val: "false".to_string(), - }), - }), - ASSIGN(Assign { - left: VAR(Var { id: 47 }), - right: Value::CONST(Const { - val: "_".to_string(), - }), - }), - ASSIGN(Assign { - left: VAR(Var { id: 33 }), - right: VAR(Var { id: 34 }), - }), - ASSIGN(Assign { - left: VAR(Var { id: 48 }), - right: Value::CONST(Const { - val: "_".to_string(), - }), - }), - ASSIGN(Assign { - left: VAR(Var { id: 49 }), - right: Value::CONST(Const { - val: "false".to_string(), - }), - }), - ASSIGN(Assign { - left: VAR(Var { id: 50 }), - right: Value::CONST(Const { - val: "false".to_string(), - }), - }), - ASSIGN(Assign { - left: VAR(Var { id: 32 }), - right: Value::CONST(Const { - val: "false".to_string(), - }), - }), - ASSIGN(Assign { - left: VAR(Var { id: 4 }), - right: VAR(Var { id: 5 }), - }), - ASSIGN(Assign { - left: VAR(Var { id: 32 }), - right: Value::CONST(Const { - val: "true".to_string(), - }), - }), - ASSIGN(Assign { - left: VAR(Var { id: 7 }), - right: Value::CONST(Const { - val: "0_i32".to_string(), - }), - }), - ASSIGN(Assign { - left: VAR(Var { id: 9 }), - right: VAR(Var { id: 7 }), - }), - ASSIGN(Assign { - left: VAR(Var { id: 16 }), - right: VAR(Var { id: 17 }), - }), - ASSIGN(Assign { - left: VAR(Var { id: 32 }), - right: Value::CONST(Const { - val: "false".to_string(), - }), - }), - ASSIGN(Assign { - left: VAR(Var { id: 32 }), - right: Value::CONST(Const { - val: "true".to_string(), - }), - }), - ASSIGN(Assign { - left: VAR(Var { id: 31 }), - right: Value::CONST(Const { - val: "_".to_string(), - }), - }), - ASSIGN(Assign { - left: VAR(Var { id: 32 }), - right: Value::CONST(Const { - val: "false".to_string(), - }), - }), - MOVE(Move { - left: VAR(Var { id: 19 }), - right: VAR(Var { id: 2 }), - }), - MOVE(Move { - left: VAR(Var { id: 38 }), - right: VAR(Var { id: 9 }), - }), - MOVE(Move { - left: VAR(Var { id: 2 }), - right: VAR(Var { id: 14 }), - }), - REF(Reference { - src: VAR(Var { id: 6 }), - dst: VAR(Var { id: 1 }), - }), - REF(Reference { - src: VAR(Var { id: 8 }), - dst: VAR(Var { id: 3 }), - }), - REF(Reference { - src: VAR(Var { id: 20 }), - dst: VAR(Var { id: 1 }), - }), - REF(Reference { - src: VAR(Var { id: 15 }), - dst: VAR(Var { id: 16 }), - }), - REF(Reference { - src: VAR(Var { id: 31 }), - dst: VAR(Var { id: 11 }), - }), - REF(Reference { - src: VAR(Var { id: 28 }), - dst: VAR(Var { id: 29 }), - }), - REF(Reference { - src: VAR(Var { id: 35 }), - dst: VAR(Var { id: 3 }), - }), - REF(Reference { - src: VAR(Var { id: 46 }), - dst: VAR(Var { id: 1 }), - }), - REF(Reference { - src: VAR(Var { id: 43 }), - dst: VAR(Var { id: 44 }), - }), - REF(Reference { - src: VAR(Var { id: 0 }), - dst: VAR(Var { id: 1 }), - }), - REF(Reference { - src: VAR(Var { id: 13 }), - dst: VAR(Var { id: 2 }), - }), - REF(Reference { - src: VAR(Var { id: 21 }), - dst: VAR(Var { id: 2 }), - }), - REF(Reference { - src: VAR(Var { id: 30 }), - dst: VAR(Var { id: 7 }), - }), - REF(Reference { - src: VAR(Var { id: 27 }), - dst: VAR(Var { id: 28 }), - }), - REF(Reference { - src: VAR(Var { id: 0 }), - dst: VAR(Var { id: 1 }), - }), - CALL(Call { - ret: Var { id: 2 }, - label: "Mutex::::new".to_string(), - params: vec![Param::COSNT(Const { - val: "const false".to_string(), - })], - next_block: "bb1;".to_string(), - unwind_block: None, - }), - CALL(Call { - ret: Var { id: 1 }, - label: "Arc::>::new".to_string(), - params: vec![Param::MOVE(Var { id: 2 })], - next_block: "bb2;".to_string(), - unwind_block: None, - }), - CALL(Call { - ret: Var { id: 4 }, - label: "Condvar::new".to_string(), - params: vec![], - next_block: "bb3".to_string(), - unwind_block: Some("bb32".to_string()), - }), - CALL(Call { - ret: Var { id: 3 }, - label: "Arc::::new".to_string(), - params: vec![Param::MOVE(Var { id: 4 })], - next_block: "bb4".to_string(), - unwind_block: Some("bb32".to_string()), - }), - CALL(Call { - ret: Var { id: 5 }, - label: "> as Clone>::clone".to_string(), - params: vec![Param::MOVE(Var { id: 6 })], - next_block: "bb5".to_string(), - unwind_block: Some("bb31".to_string()), - }), - CALL(Call { - ret: Var { id: 7 }, - label: " as Clone>::clone".to_string(), - params: vec![Param::MOVE(Var { id: 8 })], - next_block: "bb6".to_string(), - unwind_block: Some("bb37".to_string()), - }), - CALL(Call { - ret: Var { id: 9 }, - label: "spawn::<[closure@src/main.rs:11:21: 11:28], ()>".to_string(), - params: vec![Param::MOVE(Var { id: 10 })], - next_block: "bb7".to_string(), - unwind_block: Some("bb37".to_string()), - }), - CALL(Call { - ret: Var { id: 13 }, - label: "Duration::from_millis".to_string(), - params: vec![Param::COSNT(Const { - val: "const 1000_u64".to_string(), - })], - next_block: "bb9".to_string(), - unwind_block: Some("bb35".to_string()), - }), - CALL(Call { - ret: Var { id: 12 }, - label: "sleep".to_string(), - params: vec![Param::MOVE(Var { id: 13 })], - next_block: "bb10".to_string(), - unwind_block: Some("bb35".to_string()), - }), - CALL(Call { - ret: Var { id: 19 }, - label: "> as Deref>::deref".to_string(), - params: vec![Param::MOVE(Var { id: 20 })], - next_block: "bb11".to_string(), - unwind_block: Some("bb35".to_string()), - }), - CALL(Call { - ret: Var { id: 17 }, - label: "Mutex::::lock".to_string(), - params: vec![Param::MOVE(Var { id: 18 })], - next_block: "bb12".to_string(), - unwind_block: Some("bb35".to_string()), - }), - CALL(Call { - ret: Var { id: 16 }, - label: "Result::, PoisonError>>::unwrap" - .to_string(), - params: vec![Param::MOVE(Var { id: 17 })], - next_block: "bb13".to_string(), - unwind_block: Some("bb35".to_string()), - }), - CALL(Call { - ret: Var { id: 14 }, - label: " as DerefMut>::deref_mut".to_string(), - params: vec![Param::MOVE(Var { id: 15 })], - next_block: "bb14".to_string(), - unwind_block: Some("bb30".to_string()), - }), - CALL(Call { - ret: Var { id: 37 }, - label: "JoinHandle::<()>::join".to_string(), - params: vec![Param::MOVE(Var { id: 38 })], - next_block: "bb23".to_string(), - unwind_block: Some("bb35".to_string()), - }), - CALL(Call { - ret: Var { id: 30 }, - label: "core::fmt::ArgumentV1::<'_>::new_display::".to_string(), - params: vec![Param::VAR(Var { id: 31 })], - next_block: "bb19".to_string(), - unwind_block: Some("bb35".to_string()), - }), - CALL(Call { - ret: Var { id: 25 }, - label: "Arguments::<'_>::new_v1".to_string(), - params: vec![Param::MOVE(Var { id: 26 }), Param::MOVE(Var { id: 27 })], - next_block: "bb20".to_string(), - unwind_block: Some("bb35".to_string()), - }), - CALL(Call { - ret: Var { id: 24 }, - label: "_print".to_string(), - params: vec![Param::MOVE(Var { id: 25 })], - next_block: "bb21".to_string(), - unwind_block: Some("bb35".to_string()), - }), - CALL(Call { - ret: Var { id: 34 }, - label: " as Deref>::deref".to_string(), - params: vec![Param::MOVE(Var { id: 35 })], - next_block: "bb22".to_string(), - unwind_block: Some("bb35".to_string()), - }), - CALL(Call { - ret: Var { id: 32 }, - label: "Condvar::notify_one".to_string(), - params: vec![Param::MOVE(Var { id: 33 })], - next_block: "bb38".to_string(), - unwind_block: Some("bb35".to_string()), - }), - CALL(Call { - ret: Var { id: 36 }, - label: "Result::<(), Box>::unwrap".to_string(), - params: vec![Param::MOVE(Var { id: 37 })], - next_block: "bb24".to_string(), - unwind_block: Some("bb35".to_string()), - }), - CALL(Call { - ret: Var { id: 45 }, - label: "core::fmt::ArgumentV1::<'_>::new_debug::>>".to_string(), - params: vec![Param::VAR(Var { id: 46 })], - next_block: "bb25".to_string(), - unwind_block: Some("bb35".to_string()), - }), - CALL(Call { - ret: Var { id: 40 }, - label: "Arguments::<'_>::new_v1".to_string(), - params: vec![Param::MOVE(Var { id: 41 }), Param::MOVE(Var { id: 42 })], - next_block: "bb26".to_string(), - unwind_block: Some("bb35".to_string()), - }), - CALL(Call { - ret: Var { id: 39 }, - label: "_print".to_string(), - params: vec![Param::MOVE(Var { id: 40 })], - next_block: "bb27".to_string(), - unwind_block: Some("bb35".to_string()), - }), - CALL(Call { - ret: Var { id: 5 }, - label: "> as Deref>::deref".to_string(), - params: vec![Param::MOVE(Var { id: 6 })], - next_block: "bb1".to_string(), - unwind_block: Some("bb19".to_string()), - }), - CALL(Call { - ret: Var { id: 3 }, - label: "Mutex::::lock".to_string(), - params: vec![Param::MOVE(Var { id: 4 })], - next_block: "bb2".to_string(), - unwind_block: Some("bb19".to_string()), - }), - CALL(Call { - ret: Var { id: 2 }, - label: "Result::, PoisonError>>::unwrap" - .to_string(), - params: vec![Param::MOVE(Var { id: 3 })], - next_block: "bb3".to_string(), - unwind_block: Some("bb19".to_string()), - }), - CALL(Call { - ret: Var { id: 12 }, - label: " as Deref>::deref".to_string(), - params: vec![Param::MOVE(Var { id: 13 })], - next_block: "bb6".to_string(), - unwind_block: Some("bb22".to_string()), - }), - CALL(Call { - ret: Var { id: 17 }, - label: " as Deref>::deref".to_string(), - params: vec![Param::MOVE(Var { id: 18 })], - next_block: "bb8".to_string(), - unwind_block: Some("bb22".to_string()), - }), - CALL(Call { - ret: Var { id: 15 }, - label: "Condvar::wait::".to_string(), - params: vec![Param::MOVE(Var { id: 16 }), Param::MOVE(Var { id: 19 })], - next_block: "bb9".to_string(), - unwind_block: Some("bb22".to_string()), - }), - CALL(Call { - ret: Var { id: 14 }, - label: "Result::, PoisonError>>::unwrap" - .to_string(), - params: vec![Param::MOVE(Var { id: 15 })], - next_block: "bb10".to_string(), - unwind_block: Some("bb22".to_string()), - }), - CALL(Call { - ret: Var { id: 20 }, - label: " as DerefMut>::deref_mut".to_string(), - params: vec![Param::MOVE(Var { id: 21 })], - next_block: "bb12".to_string(), - unwind_block: Some("bb22".to_string()), - }), - CALL(Call { - ret: Var { id: 29 }, - label: "core::fmt::ArgumentV1::<'_>::new_display::".to_string(), - params: vec![Param::VAR(Var { id: 30 })], - next_block: "bb14".to_string(), - unwind_block: Some("bb22".to_string()), - }), - CALL(Call { - ret: Var { id: 24 }, - label: "Arguments::<'_>::new_v1".to_string(), - params: vec![Param::MOVE(Var { id: 25 }), Param::MOVE(Var { id: 26 })], - next_block: "bb15".to_string(), - unwind_block: Some("bb22".to_string()), - }), - CALL(Call { - ret: Var { id: 23 }, - label: "_print".to_string(), - params: vec![Param::MOVE(Var { id: 24 })], - next_block: "bb23".to_string(), - unwind_block: Some("bb22".to_string()), - }), - MIR::FIELDACCESS(FIELDACCESS::MOVE(FieldAccess { - left: Var { id: 11 }, - struct_var: Var { id: 21 }, - field_num: 0, - })), - MIR::FIELDACCESS(FIELDACCESS::REF(FieldAccess { - left: Var { id: 6 }, - struct_var: Var { id: 1 }, - field_num: 0, - })), - MIR::FIELDACCESS(FIELDACCESS::REF(FieldAccess { - left: Var { id: 18 }, - struct_var: Var { id: 1 }, - field_num: 1, - })), - MIR::FIELDACCESS(FIELDACCESS::MOVE(FieldAccess { - left: Var { id: 7 }, - struct_var: Var { id: 22 }, - field_num: 0, - })), - ]; - - results - .iter() - .for_each(|r| assert!(std_results.contains(r))); - std_results - .iter() - .for_each(|r| assert!(results.contains(r))); - } - - #[test] - fn test_read_mir_field_access() { - use super::MIR::{ASSIGN, CALL, REF}; - use crate::mir_analyze::mirs::mir::{Assign, Call, Const, Param, Value, Value::VAR, Var}; - - use crate::mir_analyze::analyze::reader::read_mir; - use std::path::PathBuf; - - let mir_file = PathBuf::from("test/mir_analyze/reader/field-access.mir"); - - let results = read_mir(mir_file).unwrap(); - - let std_results = vec![ - ASSIGN(Assign { - left: VAR(Var { id: 16 }), - right: Value::CONST(Const { - val: "false".to_string(), - }), - }), - CALL(Call { - ret: Var { id: 2 }, - label: ">::from".to_string(), - params: vec![Param::COSNT(Const { - val: "const \"string\"".to_string(), - })], - next_block: "bb1".to_string(), - unwind_block: Some("continue".to_string()), - }), - ASSIGN(Assign { - left: VAR(Var { id: 16 }), - right: Value::CONST(Const { - val: "true".to_string(), - }), - }), - ASSIGN(Assign { - left: VAR(Var { id: 15 }), - right: Value::CONST(Const { - val: "_".to_string(), - }), - }), - MIR::FIELDACCESS(FIELDACCESS::REF(FieldAccess { - left: Var { id: 10 }, - struct_var: Var { id: 1 }, - field_num: 0, - })), - CALL(Call { - ret: Var { id: 9 }, - label: "core::fmt::rt::Argument::<'_>::new_display::".to_string(), - params: vec![Param::VAR(Var { id: 10 })], - next_block: "bb2".to_string(), - unwind_block: Some("bb10".to_string()), - }), - REF(Reference { - src: VAR(Var { id: 7 }), - dst: VAR(Var { id: 8 }), - }), - CALL(Call { - ret: Var { id: 4 }, - label: "Arguments::<'_>::new_v1".to_string(), - params: vec![Param::MOVE(Var { id: 5 }), Param::MOVE(Var { id: 6 })], - next_block: "bb3".to_string(), - unwind_block: Some("bb10".to_string()), - }), - CALL(Call { - ret: Var { id: 3 }, - label: "_print".to_string(), - params: vec![Param::MOVE(Var { id: 4 })], - next_block: "bb4".to_string(), - unwind_block: Some("bb10".to_string()), - }), - ASSIGN(Assign { - left: VAR(Var { id: 16 }), - right: Value::CONST(Const { - val: "false".to_string(), - }), - }), - MIR::FIELDACCESS(FIELDACCESS::MOVE(FieldAccess { - left: Var { id: 12 }, - struct_var: Var { id: 1 }, - field_num: 0, - })), - MIR::FIELDACCESS(FIELDACCESS::REFMUT(FieldAccess { - left: Var { id: 14 }, - struct_var: Var { id: 11 }, - field_num: 0, - })), - CALL(Call { - ret: Var { id: 13 }, - label: "String::clear".to_string(), - params: vec![Param::MOVE(Var { id: 14 })], - next_block: "bb5".to_string(), - unwind_block: Some("bb7".to_string()), - }), - ASSIGN(Assign { - left: VAR(Var { id: 16 }), - right: Value::CONST(Const { - val: "false".to_string(), - }), - }), - REF(Reference { - src: VAR(Var { id: 0 }), - dst: VAR(Var { id: 1 }), - }), - ]; - - results - .iter() - .for_each(|r| assert!(std_results.contains(r))); - std_results - .iter() - .for_each(|r| assert!(results.contains(r))); - } -} diff --git a/collector/src/mir_analyze/data/analyze_data.rs b/collector/src/mir_analyze/data/analyze_data.rs deleted file mode 100644 index ccc1c3e..0000000 --- a/collector/src/mir_analyze/data/analyze_data.rs +++ /dev/null @@ -1,37 +0,0 @@ -use std::{collections::HashMap, path::Path}; - -use crate::mir_analyze::{analyze::count::MirCount, mirs::mir::MIR}; - -use super::table_data::{write_tex_table, TableDatas}; - -pub struct Data { - mir_count: TableDatas, -} - -impl Data { - pub fn new() -> Self { - Self { - mir_count: MIR::get_all_types() - .into_iter() - .map(|mir_item| (mir_item, HashMap::default())) - .collect(), - } - } - - pub fn add_mir_count(&mut self, benchmark: &String, mir_count: MirCount) { - self.mir_count.iter_mut().for_each(|(mir_item, v)| { - v.insert(benchmark.clone(), *mir_count.get(mir_item).unwrap()); - }) - } - - pub fn write_all(self, out_dir: &Path) -> anyhow::Result<()> { - write_tex_table( - &self.mir_count, - out_dir, - "MIR Count".to_string(), - "MIR Count".to_string(), - )?; - - Ok(()) - } -} diff --git a/collector/src/mir_analyze/data/mod.rs b/collector/src/mir_analyze/data/mod.rs index 56d4a19..5ec8c25 100644 --- a/collector/src/mir_analyze/data/mod.rs +++ b/collector/src/mir_analyze/data/mod.rs @@ -1,2 +1,2 @@ -pub mod analyze_data; pub mod table_data; +pub mod tex_writer; diff --git a/collector/src/mir_analyze/mir_analyze.rs b/collector/src/mir_analyze/mir_analyze.rs index c1e110e..9900329 100644 --- a/collector/src/mir_analyze/mir_analyze.rs +++ b/collector/src/mir_analyze/mir_analyze.rs @@ -1,37 +1,173 @@ -use std::path::PathBuf; - -use crate::{ - benchmark::benchmark::Benchamrk, compile_time::discover_benchmark_suit, - toolchain::LocalToolchain, +use std::{ + collections::HashMap, + fmt::Display, + fs::{read_dir, File}, + io::BufWriter, + path::{Path, PathBuf}, }; +use anyhow::{bail, Context}; + use super::{ - analyze::count::count_mir, data::analyze_data::Data, mir_generate::generate_mir, mirs::mir::MIR, + data::table_data::TableDatas, + mir::{ + function_pattern::{count_closure, count_pure_function, higher_function}, + io_function::count_io_metrics, + oop_pattern::{dfc, lof, pbf, wms_noc_rfs}, + parallelism::{count_parallelism_metrics, count_parallelism_strcut}, + reader::parse_mir, + }, }; /// Get all benchmark directories from `benchmark_dir` and /// generate mir file for each benchmark. Then do analysis /// on the generated mir file. -pub(crate) fn entry( - ltc: LocalToolchain, - benchmarks_dir: PathBuf, - out_dir: PathBuf, -) -> anyhow::Result<()> { - let mut data = Data::new(); +pub(crate) fn entry(mir_dir: PathBuf, out_path: PathBuf) -> anyhow::Result { + let mir_suit = discover_mir_suit(mir_dir.as_path())?; + println!( + "Find mir_suit:\n{}", + mir_suit + .iter() + .map(|m| format!("+{}", m.to_string())) + .collect::() + ); + + let result = do_analyze(&mir_suit); + + serde_json::to_writer(BufWriter::new(File::create(&out_path)?), &result)?; + + Ok(out_path) +} - for benchmark in &discover_benchmark_suit(&benchmarks_dir)? { - let mirs = generate_mir(benchmark, <c)?; +fn discover_mir_suit(dir: &Path) -> anyhow::Result> { + let mut mir_suit = vec![]; - do_analyze(mirs, benchmark, &mut data)?; + for entry in read_dir(dir) + .with_context(|| format!("failed to list benchmark dir '{}'", dir.display()))? + { + let entry = entry?; + let path = entry.path(); + let name = match entry.file_name().into_string() { + core::result::Result::Ok(s) => s, + Err(e) => bail!("non-utf8 benchmark name: {:?}", e), + }; + if !entry.file_type()?.is_dir() { + println!("File '{}' ignored", name); + continue; + } + mir_suit.push(MirSource::from(path.as_path())); + } + if mir_suit.is_empty() { + eprintln!("Error: no benchmark found in '{}'", dir.display()); } + Ok(mir_suit) +} + +fn do_analyze(mir_suit: &Vec) -> TableDatas { + let mut table_data = HashMap::new(); + + let metrics = vec![ + "io_call", + "parallelism_call", + "parallelism_struct", + "oop_lof", + "oop_dfc", + "oop_pbf", + "oop_wms", + "oop_rfs", + "oop_noc", + "pure_function", + "closure", + "higher_function", + ]; - data.write_all(out_dir.as_path())?; + metrics.iter().for_each(|s| { + table_data.insert(s.to_string(), HashMap::new()); + }); - Ok(()) + for mir_source in mir_suit { + println!("Analyzing {}...", mir_source.name); + + metrics.iter().for_each(|m| { + table_data + .get_mut(&m.to_string()) + .unwrap() + .insert(mir_source.name.clone(), 0); + }); + + for mir_file in &mir_source.mirs { + let mir = &parse_mir(File::open(mir_file.clone()).unwrap()).unwrap(); + let wms_noc_rfs = wms_noc_rfs(mir); + vec![ + ("io_call".to_string(), count_io_metrics(mir)), + ( + "parallelism_call".to_string(), + count_parallelism_metrics(mir), + ), + ( + "parallelism_struct".to_string(), + count_parallelism_strcut(mir), + ), + ("oop_lof".to_string(), lof(mir)), + ("oop_dfc".to_string(), dfc(mir)), + ("oop_pbf".to_string(), pbf(mir)), + ("oop_wms".to_string(), wms_noc_rfs[0]), + ("oop_rfs".to_string(), wms_noc_rfs[1]), + ("oop_noc".to_string(), wms_noc_rfs[2]), + ("pure_function".to_string(), count_pure_function(mir)), + ("closure".to_string(), count_closure(mir)), + ("higher_function".to_string(), higher_function(mir)), + ] + .into_iter() + .for_each(|(k, v)| { + *table_data + .get_mut(&k) + .unwrap() + .get_mut(&mir_source.name) + .unwrap() += v; + }); + } + } + + table_data +} +struct MirSource { + pub name: String, + pub path: PathBuf, + pub mirs: Vec, } -fn do_analyze(mirs: Vec, benchmark: &Benchamrk, data: &mut Data) -> anyhow::Result<()> { - data.add_mir_count(&benchmark.name, count_mir(&mirs)?); +impl From<&Path> for MirSource { + fn from(d: &Path) -> Self { + assert!(d.is_dir()); + let mut mirs = vec![]; - Ok(()) + for entry in read_dir(d).unwrap() { + let entry = entry.unwrap(); + if entry.path().is_file() && entry.file_name().to_str().unwrap().ends_with(".mir") { + mirs.push(entry.path()) + } + } + + Self { + name: d.file_name().unwrap().to_str().unwrap().to_string(), + path: d.to_path_buf(), + mirs, + } + } +} + +impl Display for MirSource { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{} {}\n{}", + self.name, + self.path.to_str().unwrap(), + self.mirs + .iter() + .map(|m| format!("\t{}\n", m.to_str().unwrap())) + .collect::() + ) + } } diff --git a/collector/src/mir_analyze/mir_generate.rs b/collector/src/mir_analyze/mir_generate.rs index ced6d20..2bc11b3 100644 --- a/collector/src/mir_analyze/mir_generate.rs +++ b/collector/src/mir_analyze/mir_generate.rs @@ -1,30 +1,41 @@ use std::{ - fs::read_dir, + fs::{copy, create_dir_all, read_dir}, path::{Path, PathBuf}, process::{Command, Stdio}, }; -use anyhow::bail; - use crate::{benchmark::benchmark::Benchamrk, toolchain::LocalToolchain}; -use super::{analyze::reader::read_mir, mirs::mir::MIR}; +pub fn generate_mir( + benchmark: &Benchamrk, + ltc: &LocalToolchain, + out_path: &Path, +) -> anyhow::Result> { + println!("Generating MIR for `{}`", benchmark.name); + + let out_dir = out_path.join(&benchmark.name); + create_dir_all(&out_dir)?; -pub fn generate_mir(benchmark: &Benchamrk, ltc: &LocalToolchain) -> anyhow::Result> { match benchmark .config .compile_time_type .clone() .unwrap_or_default() { - crate::benchmark::benchmark::CompileTimeType::Single => single_genrate_mir(benchmark, ltc), + crate::benchmark::benchmark::CompileTimeType::Single => { + single_genrate_mir(benchmark, ltc, out_dir.as_path()) + } crate::benchmark::benchmark::CompileTimeType::Packages => { - package_generate_mir(benchmark, ltc) + package_generate_mir(benchmark, ltc, out_dir.as_path()) } } } -fn single_genrate_mir(benchmark: &Benchamrk, ltc: &LocalToolchain) -> anyhow::Result> { +fn single_genrate_mir( + benchmark: &Benchamrk, + ltc: &LocalToolchain, + out_path: &Path, +) -> anyhow::Result> { let tmp_dir = benchmark.make_temp_dir(&benchmark.path)?; let mut cmd = Command::new(Path::new(<c.cargo)); @@ -43,8 +54,7 @@ fn single_genrate_mir(benchmark: &Benchamrk, ltc: &LocalToolchain) -> anyhow::Re .env("RUSTC_BOOTSTRAP", "1") .current_dir(tmp_dir.path()) .arg("rustc") - .arg("--profile") - .arg("release") + .arg("--release") .arg("--manifest-path") .arg( &benchmark @@ -52,18 +62,20 @@ fn single_genrate_mir(benchmark: &Benchamrk, ltc: &LocalToolchain) -> anyhow::Re .cargo_toml .clone() .unwrap_or_else(|| String::from("Cargo.toml")), - ) - .arg("--") - .arg("--emit=mir"); + ); + if let Some(opts) = &benchmark.config.cargo_opts { + cmd.args(opts.split(" ").collect::>()); + } + cmd.arg("--").arg("--emit=mir"); - cmd.stdout(Stdio::piped()) - .stderr(Stdio::piped()) + cmd.stdout(Stdio::null()) + .stderr(Stdio::null()) .spawn() .expect(format!("Fail to compile {}.", benchmark.name).as_str()) .wait()?; // find mir file - let mut mir_file = None; + let mut mir_files = vec![]; for entry in read_dir(PathBuf::from( tmp_dir.path().join("target").join("release").join("deps"), ))? { @@ -71,23 +83,20 @@ fn single_genrate_mir(benchmark: &Benchamrk, ltc: &LocalToolchain) -> anyhow::Re if let Some(file_name) = entry.file_name().to_str() { if file_name.ends_with(".mir") { - mir_file = Some(entry.path()); + let dst_path = out_path.join(entry.file_name()); + copy(entry.path(), &dst_path)?; + mir_files.push(dst_path); } } } - - // if mir file found, extract mirs; else return err. - if let Some(mir_file) = mir_file { - read_mir(mir_file) - } else { - bail!(format!( - "Mir file not found after {} compiled", - benchmark.name - )) - } + Ok(mir_files) } -fn package_generate_mir(benchmark: &Benchamrk, ltc: &LocalToolchain) -> anyhow::Result> { +fn package_generate_mir( + benchmark: &Benchamrk, + ltc: &LocalToolchain, + out_path: &Path, +) -> anyhow::Result> { let tmp_dir = benchmark.make_temp_dir(&benchmark.path)?; for package in benchmark.config.packages.clone().unwrap() { @@ -102,8 +111,7 @@ fn package_generate_mir(benchmark: &Benchamrk, ltc: &LocalToolchain) -> anyhow:: .env("RUSTC_BOOTSTRAP", "1") .current_dir(tmp_dir.path()) .arg("rustc") - .arg("--profile") - .arg("release") + .arg("--release") .arg("--manifest-path") .arg( &benchmark @@ -113,18 +121,20 @@ fn package_generate_mir(benchmark: &Benchamrk, ltc: &LocalToolchain) -> anyhow:: .unwrap_or_else(|| String::from("Cargo.toml")), ) .arg("--package") - .arg(package) - .arg("--") - .arg("--emit=mir"); + .arg(package); + if let Some(opts) = &benchmark.config.cargo_opts { + cmd.args(opts.split(" ").collect::>()); + } + cmd.arg("--").arg("--emit=mir"); - cmd.stdout(Stdio::piped()) - .stderr(Stdio::piped()) + cmd.stdout(Stdio::null()) + .stderr(Stdio::null()) .spawn() .expect(format!("Fail to compile {}.", benchmark.name).as_str()) .wait()?; } - let mut mirs = vec![]; + let mut mir_files = vec![]; for entry in read_dir(PathBuf::from( tmp_dir.path().join("target").join("release").join("deps"), ))? { @@ -132,17 +142,22 @@ fn package_generate_mir(benchmark: &Benchamrk, ltc: &LocalToolchain) -> anyhow:: if let Some(file_name) = entry.file_name().to_str() { if file_name.ends_with(".mir") { - mirs.append(&mut read_mir(entry.path())?); + let dst_path = out_path.join(entry.file_name()); + copy(entry.path(), &dst_path)?; + mir_files.push(dst_path); } } } - Ok(mirs) + Ok(mir_files) } #[cfg(test)] mod test { - use std::path::PathBuf; + use std::{ + fs::remove_dir_all, + path::{Path, PathBuf}, + }; use crate::{ benchmark::benchmark::{Benchamrk, BenchmarkConfig}, @@ -174,8 +189,9 @@ mod test { runtime_test_packages: None, }, }; + let out_dir = Path::new("test/mir_analyze/run_analyze/out"); - generate_mir( + let v = generate_mir( &benchmark, &LocalToolchain { rustc: PathBuf::from("rustc"), @@ -183,8 +199,16 @@ mod test { flame_graph: PathBuf::from(""), id: 0.to_string(), }, + &out_dir, ) .unwrap(); + + assert!(v.len() > 0); + v.into_iter().for_each(|f| { + f.metadata().unwrap(); + }); + + remove_dir_all(out_dir.join("condvar")).unwrap(); } /// Test mir generation when handling benchmark programs made of several packages. @@ -196,7 +220,9 @@ mod test { ) .unwrap(); - generate_mir( + let out_dir = Path::new("test/mir_analyze/run_analyze/out"); + + let v = generate_mir( &benchmark, &LocalToolchain { rustc: PathBuf::from("rustc"), @@ -204,7 +230,14 @@ mod test { flame_graph: PathBuf::from(""), id: 0.to_string(), }, + out_dir, ) .unwrap(); + + assert!(v.len() > 0); + v.into_iter().for_each(|f| { + f.metadata().unwrap(); + }); + remove_dir_all(out_dir.join("muti-package")).unwrap(); } } diff --git a/collector/src/mir_analyze/mirs/mir.rs b/collector/src/mir_analyze/mirs/mir.rs deleted file mode 100644 index 18b7bd8..0000000 --- a/collector/src/mir_analyze/mirs/mir.rs +++ /dev/null @@ -1,324 +0,0 @@ -use regex::Regex; - -#[derive(Debug)] -pub enum MIR { - ASSIGN(Assign), - REF(Reference), - MOVE(Move), - CALL(Call), - FIELDACCESS(FIELDACCESS), -} - -pub static ASSIGN_TYPE: &str = "assignment"; -pub static REF_TYPE: &str = "reference"; -pub static MOVE_TYPE: &str = "move"; -pub static CALL_TYPE: &str = "call"; -pub static FIELD_ACCESS_TYPE: &str = "field acess"; - -impl MIR { - pub fn get_all_types() -> Vec { - vec![ - ASSIGN_TYPE.to_string(), - REF_TYPE.to_string(), - MOVE_TYPE.to_string(), - CALL_TYPE.to_string(), - FIELD_ACCESS_TYPE.to_string(), - ] - } - - pub fn get_type(&self) -> String { - match self { - MIR::ASSIGN(_) => ASSIGN_TYPE.to_string(), - MIR::REF(_) => REF_TYPE.to_string(), - MIR::MOVE(_) => MOVE_TYPE.to_string(), - MIR::CALL(_) => CALL_TYPE.to_string(), - MIR::FIELDACCESS(_) => FIELD_ACCESS_TYPE.to_string(), - } - } -} - -pub type VarId = u32; - -#[derive(Debug)] -pub struct Assign { - pub left: Value, - pub right: Value, -} - -#[derive(Debug)] -pub enum FIELDACCESS { - MOVE(FieldAccess), - REF(FieldAccess), - REFMUT(FieldAccess), -} - -#[derive(Debug)] -pub struct FieldAccess { - pub left: Var, - pub struct_var: Var, - pub field_num: u32, -} - -#[derive(Debug)] -pub struct Reference { - pub src: Value, - pub dst: Value, -} - -#[derive(Debug)] -pub struct Move { - pub left: Value, - pub right: Value, -} - -#[derive(Debug)] -pub struct Call { - pub ret: Var, - pub label: String, - pub params: Vec, - pub next_block: String, - pub unwind_block: Option, -} - -#[derive(Debug)] -pub enum Param { - MOVE(Var), - VAR(Var), - COSNT(Const), -} - -#[derive(Debug)] -pub enum Value { - CONST(Const), - VAR(Var), -} - -#[derive(Debug)] -pub struct Const { - pub val: String, -} - -#[derive(Debug)] -pub struct Var { - pub id: VarId, -} - -impl MIR { - /// Match a mir from a string. - /// * type bounding `let _i = some_type` - /// * assignment `_i = _j` or `_i = cosnt xxx` - /// * move `_i = move _j` - /// * ref `_i = &_j` or `_i = &mut _j` - /// * type-cast `_i = _j as xxx` - /// * function/method call `_i = domain/type_ascription::func(args) -> [return: bb_x, unwind: bb_y] | return bb_x` - /// * switch `_i = discriminant(_j); switchInt(move _i) -> [blocks]` - /// * field access `_i = move (_j.x type) | &mut (_j.x type)| &(_j.x type)` - pub fn new(line: &String) -> Option { - for capture in MIR::get_captures() { - if let Some(mir) = capture(line) { - return Some(mir); - } - } - - None - } - - fn get_captures() -> Vec Option> { - vec![ - MIR::assignment_capture, - MIR::move_capture, - MIR::ref_capture, - MIR::call_capture, - MIR::field_access_capture, - ] - } - - /// `_i = _j` or `_i = cosnt xxx` - fn assignment_capture(line: &String) -> Option { - let assignment_pattern = Regex::new(r"(_(\d+) = (_(\d+)|(const) (.*));.*)").unwrap(); - if let Some(captures) = assignment_pattern.captures(line.as_str()) { - // Extract the first and second variables or constant - let first_var = captures.get(2).map(|m| m.as_str()).unwrap(); - let second_var_or_const = captures.get(3).map(|m| m.as_str()).unwrap(); - - if second_var_or_const.starts_with("const") { - Some(Self::ASSIGN(Assign { - left: Value::VAR(Var { - id: first_var.parse().unwrap(), - }), - right: Value::CONST(Const { - val: captures - .get(6) - .map(|m| m.as_str()) - .unwrap() - .parse() - .unwrap(), - }), - })) - } else { - Some(Self::ASSIGN(Assign { - left: Value::VAR(Var { - id: first_var.parse().unwrap(), - }), - right: Value::VAR(Var { - id: captures - .get(4) - .map(|m| m.as_str()) - .unwrap() - .parse() - .unwrap(), - }), - })) - } - } else { - None - } - } - - /// `_i = move _j` - fn move_capture(line: &String) -> Option { - let move_pattern = Regex::new(r"_(\d+) = move _(\d+)").unwrap(); - if let Some(captures) = move_pattern.captures(line.as_str()) { - let first_var = captures.get(1).map(|m| m.as_str()).unwrap(); - let second_var = captures.get(2).map(|m| m.as_str()).unwrap(); - - Some(Self::MOVE(Move { - left: Value::VAR(Var { - id: first_var.parse().unwrap(), - }), - right: Value::VAR(Var { - id: second_var.parse().unwrap(), - }), - })) - } else { - None - } - } - - /// `_i = &_j` or `_i = &mut _j` - fn ref_capture(line: &String) -> Option { - let ref_capture = Regex::new(r"_(\d+) = ((&_(\d+))|(&mut _(\d+)))").unwrap(); - if let Some(captures) = ref_capture.captures(line.as_str()) { - let first_var = captures.get(1).map(|m| m.as_str()).unwrap(); - - let second_var = if let Some(second_var) = captures.get(6).map(|m| m.as_str()) { - second_var - } else { - captures.get(4).map(|m| m.as_str()).unwrap() - }; - - Some(Self::REF(Reference { - src: (Value::VAR(Var { - id: first_var.parse().unwrap(), - })), - dst: (Value::VAR(Var { - id: second_var.parse().unwrap(), - })), - })) - } else { - None - } - } - - /// `_i = domain/type_ascription::func(args) -> [return: bb_x, unwind: bb_y] | return bb_x` - fn call_capture(line: &String) -> Option { - let call_pattern = Regex::new( - r"_(\d+) = (.*)\((.*)\) -> ((\[return(.*), unwind(.*)\];)|(([a-zA-Z]+[^;]);))", - ) - .unwrap(); - if let Some(captures) = call_pattern.captures(line.as_str()) { - let params = captures.get(3).unwrap().as_str(); - - let get_block = |s| { - let bb_pattern = Regex::new(r"(: (.*))|( (.*))|(.*)").unwrap(); - let captures = bb_pattern.captures(s).unwrap(); - - if let Some(bb) = captures.get(2).map(|m| m.as_str()) { - Some(bb.to_string()) - } else if let Some(bb) = captures.get(4).map(|m| m.as_str()) { - Some(bb.to_string()) - } else if let Some(bb) = captures.get(5).map(|m| m.as_str()) { - Some(bb.to_string()) - } else { - None - } - }; - - Some(MIR::CALL(Call { - ret: Var { - id: captures.get(1).unwrap().as_str().parse().unwrap(), - }, - label: captures.get(2).unwrap().as_str().to_string(), - params: if params.is_empty() { - vec![] - } else { - params - .split(", ") - .into_iter() - .map(|param| { - let param_pattern = - Regex::new(r"(move _(\d+))|(_(\d+))|(const .*)").unwrap(); - if let Some(captures) = param_pattern.captures(param) { - if let Some(c) = captures.get(5).map(|m| m.as_str()) { - Param::COSNT(Const { val: c.to_string() }) - } else if let Some(p) = captures.get(2).map(|m| m.as_str()) { - Param::MOVE(Var { - id: p.parse().unwrap(), - }) - } else { - Param::VAR(Var { - id: captures.get(4).unwrap().as_str().parse().unwrap(), - }) - } - } else { - panic!(); - } - }) - .collect() - }, - next_block: if let Some(s) = captures.get(6).map(|m| m.as_str()) { - get_block(s).unwrap() - } else { - get_block(captures.get(8).unwrap().as_str()).unwrap() - }, - unwind_block: if let Some(s) = captures.get(7).map(|m| m.as_str()) { - get_block(s) - } else { - None - }, - })) - } else { - None - } - } - - /// `_i = move (_j.x type) | &mut (_j.x type)| &(_j.x type)` - fn field_access_capture(line: &String) -> Option { - let field_access_pattern = - Regex::new(r"_(\d+) = ((move )|(&mut )|(&))\(_(\d+)\.(\d+): .*\);.*").unwrap(); - - if let Some(captures) = field_access_pattern.captures(line) { - let field_access = FieldAccess { - left: Var { - id: captures.get(1).unwrap().as_str().parse().unwrap(), - }, - struct_var: Var { - id: captures.get(6).unwrap().as_str().parse().unwrap(), - }, - field_num: captures.get(7).unwrap().as_str().parse().unwrap(), - }; - - if captures.get(3).is_some() { - Some(MIR::FIELDACCESS(FIELDACCESS::MOVE(field_access))) - } else if captures.get(4).is_some() { - Some(MIR::FIELDACCESS(FIELDACCESS::REFMUT(field_access))) - } else if captures.get(5).is_some() { - Some(MIR::FIELDACCESS(FIELDACCESS::REF(field_access))) - } else { - panic!("Fail to capture {} as field access statement.", line); - } - } else { - None - } - } -} diff --git a/collector/src/mir_analyze/mirs/mod.rs b/collector/src/mir_analyze/mirs/mod.rs deleted file mode 100644 index d8bb7a1..0000000 --- a/collector/src/mir_analyze/mirs/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub(super) mod mir; diff --git a/collector/src/mir_analyze/mod.rs b/collector/src/mir_analyze/mod.rs index f577472..1609abd 100644 --- a/collector/src/mir_analyze/mod.rs +++ b/collector/src/mir_analyze/mod.rs @@ -1,6 +1,4 @@ -mod analyze; pub(crate) mod data; mod mir; pub(crate) mod mir_analyze; -mod mir_generate; -mod mirs; +pub(crate) mod mir_generate; diff --git a/collector/src/toolchain.rs b/collector/src/toolchain.rs index 857d5cd..0a4634c 100644 --- a/collector/src/toolchain.rs +++ b/collector/src/toolchain.rs @@ -371,16 +371,13 @@ pub enum Commands { /// Analyze MIRs generated from benchmarks. MirAnalyze { - #[clap(flatten)] - local: LocalOptions, - - /// The path of benchmark dir - #[clap(long = "bench-dir", default_value = "../benchmarks/compile-time")] - bench_dir: PathBuf, + /// The path of dir contains mir files grouped by benchmark name + #[clap(long = "mir-dir", default_value = "../benchmarks/compile-time")] + mir_dir: PathBuf, /// The path of output file - #[clap(long = "out-dir", default_value = "results")] - out_dir: PathBuf, + #[clap(long = "out-path", default_value = "results")] + out_path: PathBuf, }, }