Skip to content

Commit d095a76

Browse files
committed
feat: Implement noneOf inst combine matcher
1 parent c0fdd3c commit d095a76

File tree

3 files changed

+52
-10
lines changed

3 files changed

+52
-10
lines changed

docs/InstructionMatcher.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -163,14 +163,15 @@ Instructions Matchers are functions that build a instruction matcher to match ag
163163

164164
### Combine Instructions Matchers functions
165165

166-
| Function | Parameters | Return | Description |
167-
| :------------------: | :----------------------------------: | :---------: | :------------------------------------------------------------------------------: |
168-
| m_inst_combine_oneof | (inst: ...InstMatcher) | InstMatcher | Build Inst Matcher from list of matchers that return true if one of them matches |
169-
| m_inst_combine_allof | (inst: ...InstMatcher) | InstMatcher | Build Inst Matcher from list of matchers that return true if all of them matches |
170-
| m_inst_combine_and | (lhs: InstMatcher, rhs: InstMatcher) | InstMatcher | Build Inst Matcher two matchers that return true if (lhs and rhs) = true |
171-
| m_inst_combine_or | (lhs: InstMatcher, rhs: InstMatcher) | InstMatcher | Build Inst Matcher two matchers that return true if (lhs or rhs) = true |
172-
| m_inst_combine_xor | (lhs: InstMatcher, rhs: InstMatcher) | InstMatcher | Build Inst Matcher two matchers that return true if (lhs xor rhs )= true |
173-
| m_inst_combine_not | (rhs: InstMatcher) | InstMatcher | Build Inst Matcher two matchers that return true if (!rhs) = true |
166+
| Function | Parameters | Return | Description |
167+
| :-------------------: | :----------------------------------: | :---------: | :------------------------------------------------------------------------------------: |
168+
| m_inst_combine_oneof | (inst: ...InstMatcher) | InstMatcher | Build Inst Matcher from list of matchers that return true if one of them matches |
169+
| m_inst_combine_allof | (inst: ...InstMatcher) | InstMatcher | Build Inst Matcher from list of matchers that return true if all of them matches |
170+
| m_inst_combine_noneof | (inst: ...InstMatcher) | InstMatcher | Build Inst Matcher from list of matchers that return true if all of them don't matches |
171+
| m_inst_combine_and | (lhs: InstMatcher, rhs: InstMatcher) | InstMatcher | Build Inst Matcher two matchers that return true if (lhs and rhs) = true |
172+
| m_inst_combine_or | (lhs: InstMatcher, rhs: InstMatcher) | InstMatcher | Build Inst Matcher two matchers that return true if (lhs or rhs) = true |
173+
| m_inst_combine_xor | (lhs: InstMatcher, rhs: InstMatcher) | InstMatcher | Build Inst Matcher two matchers that return true if (lhs xor rhs )= true |
174+
| m_inst_combine_not | (rhs: InstMatcher) | InstMatcher | Build Inst Matcher two matchers that return true if (!rhs) = true |
174175

175176
### Combine Instructions Matchers Operators
176177

src/functions/matchers/combine.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use crate::matchers::InstMatcher;
1717
pub fn register_combine_matchers_function(map: &mut HashMap<&'static str, StandardFunction>) {
1818
map.insert("m_inst_combine_oneof", match_oneof_combine_inst);
1919
map.insert("m_inst_combine_allof", match_allof_combine_inst);
20+
map.insert("m_inst_combine_noneof", match_noneof_combine_inst);
2021

2122
map.insert("m_inst_combine_and", match_and_combine_inst);
2223
map.insert("m_inst_combine_or", match_or_combine_inst);
@@ -53,6 +54,19 @@ pub fn register_combine_matchers_function_signatures(map: &mut HashMap<&'static
5354
},
5455
);
5556

57+
map.insert(
58+
"m_inst_combine_noneof",
59+
Signature {
60+
parameters: vec![
61+
Box::new(InstMatcherType),
62+
Box::new(VarargsType {
63+
base: Box::new(InstMatcherType),
64+
}),
65+
],
66+
return_type: Box::new(InstMatcherType),
67+
},
68+
);
69+
5670
map.insert(
5771
"m_inst_combine_and",
5872
Signature {
@@ -108,6 +122,17 @@ fn match_allof_combine_inst(values: &[Box<dyn Value>]) -> Box<dyn Value> {
108122
Box::new(InstMatcherValue { matcher })
109123
}
110124

125+
fn match_noneof_combine_inst(values: &[Box<dyn Value>]) -> Box<dyn Value> {
126+
let mut matchers: Vec<Box<dyn InstMatcher>> = vec![];
127+
for value in values.iter() {
128+
if let Some(inst_matcher) = value.as_any().downcast_ref::<InstMatcherValue>() {
129+
matchers.push(inst_matcher.matcher.to_owned());
130+
}
131+
}
132+
let matcher = Box::new(CombineInstMatcher::create_none_of(matchers));
133+
Box::new(InstMatcherValue { matcher })
134+
}
135+
111136
fn match_and_combine_inst(values: &[Box<dyn Value>]) -> Box<dyn Value> {
112137
let (lhs, rhs) = binary_matchers_sides(values);
113138
let matcher = Box::new(CombineBinaryInstMatcher::create_and(lhs, rhs));

src/matchers/combine.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ use inkwell::llvm_sys::prelude::LLVMValueRef;
22

33
use super::InstMatcher;
44

5+
#[allow(clippy::enum_variant_names)]
56
#[derive(PartialEq, Clone)]
67
enum CombineMatcherKind {
78
OneOf,
89
AllOf,
10+
NoneOf,
911
}
1012

1113
#[derive(Clone)]
@@ -28,21 +30,34 @@ impl CombineInstMatcher {
2830
matcher_kind: CombineMatcherKind::AllOf,
2931
}
3032
}
33+
34+
pub fn create_none_of(matchers: Vec<Box<dyn InstMatcher>>) -> Self {
35+
CombineInstMatcher {
36+
matchers,
37+
matcher_kind: CombineMatcherKind::AllOf,
38+
}
39+
}
3140
}
3241

3342
impl InstMatcher for CombineInstMatcher {
3443
fn is_match(&self, instruction: LLVMValueRef) -> bool {
3544
let mut matches_count = 0;
45+
let matcher_kind = &self.matcher_kind;
3646
for matcher in self.matchers.iter() {
3747
let is_matches = matcher.is_match(instruction);
3848

3949
// If kind is `oneOf` and one if matches, return true
40-
if is_matches && self.matcher_kind == CombineMatcherKind::OneOf {
50+
if is_matches && CombineMatcherKind::OneOf.eq(matcher_kind) {
4151
return true;
4252
}
4353

4454
// If kind is `allOf` and one is not matches, return false
45-
if !is_matches && self.matcher_kind == CombineMatcherKind::AllOf {
55+
if !is_matches && CombineMatcherKind::AllOf.eq(matcher_kind) {
56+
return false;
57+
}
58+
59+
// If kind is `noneOf` and one is matches, return false
60+
if is_matches && CombineMatcherKind::NoneOf.eq(matcher_kind) {
4661
return false;
4762
}
4863

@@ -54,6 +69,7 @@ impl InstMatcher for CombineInstMatcher {
5469
match self.matcher_kind {
5570
CombineMatcherKind::OneOf => matches_count > 1,
5671
CombineMatcherKind::AllOf => matches_count == self.matchers.len(),
72+
CombineMatcherKind::NoneOf => matches_count == 0,
5773
}
5874
}
5975
}

0 commit comments

Comments
 (0)