Skip to content

Commit 6545bd5

Browse files
committed
optimize unbalanced 2-multiple shapes in relooper, prevent unnecessary nesting when the smaller is a dead end
1 parent b328775 commit 6545bd5

8 files changed

+146
-111
lines changed

src/relooper/Relooper.cpp

+43
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,49 @@ void Relooper::Calculate(Block *Entry) {
750750
}
751751
}
752752

753+
// As an optimization, if we have 2 independent groups, and one is a small dead end, we can handle only that dead end.
754+
// The other then becomes a Next - without nesting in the code and recursion in the analysis.
755+
// TODO: if the larger is the only dead end, handle that too
756+
// TODO: handle >2 groups
757+
// TODO: handle not just dead ends, but also that do not branch to the NextEntries. However, must be careful
758+
// there since we create a Next, and that Next can prevent eliminating a break (since we no longer
759+
// naturally reach the same place), which may necessitate a one-time loop, which makes the unnesting
760+
// pointless.
761+
if (IndependentGroups.size() == 2) {
762+
// Find the smaller one
763+
BlockBlockSetMap::iterator iter = IndependentGroups.begin();
764+
Block *SmallEntry = iter->first;
765+
int SmallSize = iter->second.size();
766+
iter++;
767+
Block *LargeEntry = iter->first;
768+
int LargeSize = iter->second.size();
769+
if (SmallSize != LargeSize) { // ignore the case where they are identical - keep things symmetrical there
770+
if (SmallSize > LargeSize) {
771+
Block *Temp = SmallEntry;
772+
SmallEntry = LargeEntry;
773+
LargeEntry = Temp; // Note: we did not flip the Sizes too, they are now invalid. TODO: use the smaller size as a limit?
774+
}
775+
// Check if dead end
776+
bool DeadEnd = true;
777+
BlockSet &SmallGroup = IndependentGroups[SmallEntry];
778+
for (BlockSet::iterator iter = SmallGroup.begin(); iter != SmallGroup.end(); iter++) {
779+
Block *Curr = *iter;
780+
for (BlockBranchMap::iterator iter = Curr->BranchesOut.begin(); iter != Curr->BranchesOut.end(); iter++) {
781+
Block *Target = iter->first;
782+
if (SmallGroup.find(Target) == SmallGroup.end()) {
783+
DeadEnd = false;
784+
break;
785+
}
786+
}
787+
if (!DeadEnd) break;
788+
}
789+
if (DeadEnd) {
790+
PrintDebug("Removing nesting by not handling large group because small group is dead end\n");
791+
IndependentGroups.erase(LargeEntry);
792+
}
793+
}
794+
}
795+
753796
PrintDebug("Handleable independent groups: %d\n", IndependentGroups.size());
754797

755798
if (IndependentGroups.size() > 0) {

src/relooper/test.cpp

+3-4
Original file line numberDiff line numberDiff line change
@@ -160,19 +160,19 @@ int main() {
160160

161161
puts(buffer);
162162
}
163-
/*
163+
164164
if (1) {
165165
Relooper::SetOutputBuffer(buffer, sizeof(buffer));
166166

167167
printf("\n\n-- Unbalanced with a dead end --\n\n");
168168

169169
Block *b_a = new Block("// block A\n");
170170
Block *b_b = new Block("// block B\n");
171-
Block *b_c = new Block("// block C\n");
171+
Block *b_c = new Block("return C;\n");
172172
Block *b_d = new Block("// block D\n");
173173

174174
b_a->AddBranchTo(b_b, "check == 10");
175-
b_a->AddBranchTo(b_c, NULL);
175+
b_a->AddBranchTo(b_c, NULL); // c is a dead end
176176

177177
b_b->AddBranchTo(b_d, NULL);
178178

@@ -190,6 +190,5 @@ int main() {
190190

191191
puts(buffer);
192192
}
193-
*/
194193
}
195194

src/relooper/test.txt

+22-10
Original file line numberDiff line numberDiff line change
@@ -59,24 +59,21 @@ while(1) {
5959
}
6060
// code 3
6161
if ($6) {
62-
label = 14;
6362
break;
6463
} else {
6564
var $i_0 = $7;var $x_0 = $5;
6665
}
6766
}
68-
if (label == 14) {
69-
// code 4
70-
if ($10) {
71-
// code 5
72-
}
73-
// code 6
74-
var $x_1 = $13;
67+
if (label == 18) {
7568
// code 7
7669
}
77-
else if (label == 18) {
78-
// code 7
70+
// code 4
71+
if ($10) {
72+
// code 5
7973
}
74+
// code 6
75+
var $x_1 = $13;
76+
// code 7
8077

8178

8279

@@ -97,3 +94,18 @@ if (chak()) {
9794
// block D
9895
}
9996

97+
98+
99+
-- Unbalanced with a dead end --
100+
101+
102+
103+
// block A
104+
if (!(check == 10)) {
105+
return C;
106+
}
107+
while(1) {
108+
// block B
109+
// block D
110+
}
111+

src/relooper/test_fuzz1.txt

+17-26
Original file line numberDiff line numberDiff line change
@@ -8,37 +8,28 @@ do {
88
print(7); state = check();
99
label = 3;
1010
break;
11-
} else {
12-
label = 2;
1311
}
1412
} while(0);
1513
L5: while(1) {
16-
if (label == 2) {
17-
label = 0;
18-
print(1); state = check();
19-
while(1) {
20-
print(3); state = check();
21-
if (!(state == 8)) {
22-
label = 2;
23-
continue L5;
24-
}
25-
print(8); state = check();
26-
if (!(state == 4)) {
27-
label = 3;
28-
continue L5;
29-
}
30-
print(4); state = check();
31-
if (!(state == 3)) {
32-
label = 2;
33-
continue L5;
34-
}
35-
}
36-
}
37-
else if (label == 3) {
14+
if (label == 3) {
3815
label = 0;
3916
print(2); state = check();
40-
label = 2;
41-
continue;
17+
}
18+
print(1); state = check();
19+
while(1) {
20+
print(3); state = check();
21+
if (!(state == 8)) {
22+
continue L5;
23+
}
24+
print(8); state = check();
25+
if (!(state == 4)) {
26+
label = 3;
27+
continue L5;
28+
}
29+
print(4); state = check();
30+
if (!(state == 3)) {
31+
continue L5;
32+
}
4233
}
4334
}
4435

src/relooper/test_fuzz2.txt

+4-5
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@ if (state == 1) {
55
while(1) {
66
print(1); state = check();
77
}
8-
} else {
9-
while(1) {
10-
print(3); state = check();
11-
print(2); state = check();
12-
}
8+
}
9+
while(1) {
10+
print(3); state = check();
11+
print(2); state = check();
1312
}
1413

src/relooper/test_fuzz4.txt

+9-10
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,15 @@ if (state == 2) {
55
while(1) {
66
print(2); state = check();
77
}
8-
} else {
9-
while(1) {
10-
print(4); state = check();
11-
if (!(state == 4)) {
12-
break;
13-
}
14-
}
15-
print(3); state = check();
16-
while(1) {
17-
print(1); state = check();
8+
}
9+
while(1) {
10+
print(4); state = check();
11+
if (!(state == 4)) {
12+
break;
1813
}
1914
}
15+
print(3); state = check();
16+
while(1) {
17+
print(1); state = check();
18+
}
2019

src/relooper/test_fuzz6.txt

+23-30
Original file line numberDiff line numberDiff line change
@@ -40,39 +40,14 @@ while(1) {
4040
print(16); state = check();// ................................................................................................................................................................................................................................................................................................................................................................
4141
print(57); state = check();// ...........................................................................................................................................................................................................................................................................................................................
4242
print(39); state = check();// ................
43-
if (state % 3 == 0) {
44-
label = 73;
45-
} else if (state % 3 == 1) {
43+
if (state % 3 == 1) {
4644
label = 74;
47-
} else {
45+
} else if (!(state % 3 == 0)) {
4846
label = 32;
4947
break;
5048
}
5149
while(1) {
52-
if (label == 73) {
53-
label = 0;
54-
print(72); state = check();// ..........................................................................................................
55-
if (state % 2 == 0) {
56-
label = 92;
57-
break L20;
58-
}
59-
print(80); state = check();// ....................................
60-
if (state % 2 == 0) {
61-
continue L18;
62-
}
63-
print(50); state = check();// ........................................
64-
print(29); state = check();// ...............
65-
print(8); state = check();// ....................................................................................................................................................................................................................................................
66-
if (state % 2 == 0) {
67-
continue L10;
68-
}
69-
print(19); state = check();// ......................................................................................................................................................................................................................
70-
print(56); state = check();// ....................................................................................................................................................................................................................
71-
print(34); state = check();// ..........................................................................................................................................
72-
label = 74;
73-
continue;
74-
}
75-
else if (label == 74) {
50+
if (label == 74) {
7651
label = 0;
7752
print(73); state = check();// .
7853
if (state % 3 == 1) {
@@ -87,9 +62,27 @@ while(1) {
8762
print(77); state = check();// ...........................................................................................................................................................................................................................................................................................
8863
print(76); state = check();// ..............................................................................................................................................................................................................................................................................................................................................................................................................................
8964
print(22); state = check();// .........................................................................................................
90-
label = 73;
91-
continue;
9265
}
66+
print(72); state = check();// ..........................................................................................................
67+
if (state % 2 == 0) {
68+
label = 92;
69+
break L20;
70+
}
71+
print(80); state = check();// ....................................
72+
if (state % 2 == 0) {
73+
continue L18;
74+
}
75+
print(50); state = check();// ........................................
76+
print(29); state = check();// ...............
77+
print(8); state = check();// ....................................................................................................................................................................................................................................................
78+
if (state % 2 == 0) {
79+
continue L10;
80+
}
81+
print(19); state = check();// ......................................................................................................................................................................................................................
82+
print(56); state = check();// ....................................................................................................................................................................................................................
83+
print(34); state = check();// ..........................................................................................................................................
84+
label = 74;
85+
continue;
9386
}
9487
print(62); state = check();// .......................................................................................
9588
}

src/relooper/test_inf.txt

+25-26
Original file line numberDiff line numberDiff line change
@@ -361,32 +361,31 @@ if (uint(i4) >= uint(i5)) {
361361
code 171
362362
if (i2 == 0) {
363363
code 183
364-
} else {
365-
code 172
366-
while(1) {
367-
code 173
368-
if (uint(i5) >= uint(i6)) {
369-
code 175
370-
} else {
371-
code 174
372-
}
373-
code 176
374-
if (uint(i5) >= uint(i6)) {
375-
code 178
376-
} else {
377-
code 177
378-
}
379-
code 179
380-
if (uint(i4) >= uint(i5)) {
381-
code 181
382-
} else {
383-
code 180
384-
}
385-
code 182
386-
if (!(i2 != 0)) {
387-
break;
388-
}
364+
}
365+
code 172
366+
while(1) {
367+
code 173
368+
if (uint(i5) >= uint(i6)) {
369+
code 175
370+
} else {
371+
code 174
372+
}
373+
code 176
374+
if (uint(i5) >= uint(i6)) {
375+
code 178
376+
} else {
377+
code 177
378+
}
379+
code 179
380+
if (uint(i4) >= uint(i5)) {
381+
code 181
382+
} else {
383+
code 180
384+
}
385+
code 182
386+
if (!(i2 != 0)) {
387+
break;
389388
}
390-
code 183
391389
}
390+
code 183
392391

0 commit comments

Comments
 (0)