-
Notifications
You must be signed in to change notification settings - Fork 457
/
Copy pathsimplifyBitwise.cpp
41 lines (33 loc) · 1.39 KB
/
simplifyBitwise.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include "simplifyBitwise.h"
#include "ir/pattern.h"
namespace P4 {
void SimplifyBitwise::assignSlices(const IR::Expression *expr, big_int mask) {
int one_pos = Util::scan1(mask, 0);
// Calculate the slices for this particular mask
while (one_pos >= 0) {
int zero_pos = Util::scan0(mask, one_pos);
auto left_slice = IR::Slice::make(changing_as->left, one_pos, zero_pos - 1);
auto right_slice = IR::Slice::make(expr, one_pos, zero_pos - 1);
auto new_as = changing_as->clone();
new_as->left = left_slice;
new_as->right = right_slice;
slice_statements->push_back(new_as);
one_pos = Util::scan1(mask, zero_pos);
}
}
const IR::Node *SimplifyBitwise::preorder(IR::BaseAssignmentStatement *as) {
Pattern::Match<IR::Expression> a, b;
Pattern::Match<IR::Constant> maskA, maskB;
if (!((a & maskA) | (b & maskB)).match(as->right)) return as;
if ((maskA->value & maskB->value) != 0) return as;
changing_as = as;
slice_statements = new IR::Vector<IR::StatOrDecl>();
assignSlices(a, maskA->value);
assignSlices(b, maskB->value);
big_int parameter_mask = (big_int(1) << (as->left->type->width_bits())) - 1;
parameter_mask &= ~maskA->value;
parameter_mask &= ~maskB->value;
if (parameter_mask != 0) assignSlices(new IR::Constant(0), parameter_mask);
return slice_statements;
}
} // namespace P4