69 lines
1.9 KiB
Rust
69 lines
1.9 KiB
Rust
#![cfg(feature = "normalized_dev")]
|
|
|
|
use crate::mir::join_ir::{JoinFuncId, JoinFunction, JoinInst, JoinModule};
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
pub(crate) enum NormalizedDevShape {
|
|
Pattern1Mini,
|
|
Pattern2Mini,
|
|
JsonparserSkipWsMini,
|
|
}
|
|
|
|
pub(crate) fn supported_shapes(module: &JoinModule) -> Vec<NormalizedDevShape> {
|
|
let mut shapes = Vec::new();
|
|
if is_jsonparser_skip_ws_mini(module) {
|
|
shapes.push(NormalizedDevShape::JsonparserSkipWsMini);
|
|
}
|
|
if is_pattern2_mini(module) {
|
|
shapes.push(NormalizedDevShape::Pattern2Mini);
|
|
}
|
|
if is_pattern1_mini(module) {
|
|
shapes.push(NormalizedDevShape::Pattern1Mini);
|
|
}
|
|
shapes
|
|
}
|
|
|
|
pub(crate) fn is_pattern1_mini(module: &JoinModule) -> bool {
|
|
module.is_structured() && find_loop_step(module).is_some()
|
|
}
|
|
|
|
pub(crate) fn is_pattern2_mini(module: &JoinModule) -> bool {
|
|
if !module.is_structured() || module.functions.len() != 3 {
|
|
return false;
|
|
}
|
|
let loop_func = match find_loop_step(module) {
|
|
Some(f) => f,
|
|
None => return false,
|
|
};
|
|
if !(1..=3).contains(&loop_func.params.len()) {
|
|
return false;
|
|
}
|
|
|
|
let has_cond_jump = loop_func
|
|
.body
|
|
.iter()
|
|
.any(|inst| matches!(inst, JoinInst::Jump { cond: Some(_), .. }));
|
|
let has_tail_call = loop_func
|
|
.body
|
|
.iter()
|
|
.any(|inst| matches!(inst, JoinInst::Call { k_next: None, .. }));
|
|
|
|
has_cond_jump && has_tail_call
|
|
}
|
|
|
|
pub(crate) fn is_jsonparser_skip_ws_mini(module: &JoinModule) -> bool {
|
|
is_pattern2_mini(module)
|
|
&& module
|
|
.functions
|
|
.values()
|
|
.any(|f| f.name == "jsonparser_skip_ws_mini")
|
|
}
|
|
|
|
fn find_loop_step(module: &JoinModule) -> Option<&JoinFunction> {
|
|
module
|
|
.functions
|
|
.values()
|
|
.find(|f| f.name == "loop_step")
|
|
.or_else(|| module.functions.get(&JoinFuncId::new(1)))
|
|
}
|