aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/relooper/Relooper.cpp9
-rw-r--r--src/relooper/fuzzer.py4
-rw-r--r--src/relooper/test.cpp31
-rw-r--r--src/relooper/test.txt153
-rw-r--r--tests/life.c2
5 files changed, 193 insertions, 6 deletions
diff --git a/src/relooper/Relooper.cpp b/src/relooper/Relooper.cpp
index 568dd381..9e469ec4 100644
--- a/src/relooper/Relooper.cpp
+++ b/src/relooper/Relooper.cpp
@@ -1097,7 +1097,7 @@ void Relooper::Calculate(Block *Entry) {
// Remove unneeded breaks and continues.
// A flow operation is trivially unneeded if the shape we naturally get to by normal code
// execution is the same as the flow forces us to.
- void RemoveUnneededFlows(Shape *Root, Shape *Natural=NULL, LoopShape *LastLoop=NULL) {
+ void RemoveUnneededFlows(Shape *Root, Shape *Natural=NULL, LoopShape *LastLoop=NULL, unsigned Depth=0) {
BlockSet NaturalBlocks;
FollowNaturalFlow(Natural, NaturalBlocks);
Shape *Next = Root;
@@ -1108,7 +1108,7 @@ void Relooper::Calculate(Block *Entry) {
if (Simple->Inner->BranchVar) LastLoop = NULL; // a switch clears out the loop (TODO: only for breaks, not continue)
if (Simple->Next) {
- if (!Simple->Inner->BranchVar && Simple->Inner->ProcessedBranchesOut.size() == 2) {
+ if (!Simple->Inner->BranchVar && Simple->Inner->ProcessedBranchesOut.size() == 2 && Depth < 20) {
// If there is a next block, we already know at Simple creation time to make direct branches,
// and we can do nothing more in general. But, we try to optimize the case of a break and
// a direct: This would normally be if (break?) { break; } .. but if we
@@ -1144,6 +1144,7 @@ void Relooper::Calculate(Block *Entry) {
}
}
}
+ Depth++; // this optimization increases depth, for us and all our next chain (i.e., until this call returns)
}
Next = Simple->Next;
} else {
@@ -1168,11 +1169,11 @@ void Relooper::Calculate(Block *Entry) {
}
}, {
for (IdShapeMap::iterator iter = Multiple->InnerMap.begin(); iter != Multiple->InnerMap.end(); iter++) {
- RemoveUnneededFlows(iter->second, Multiple->Next, Multiple->Breaks ? NULL : LastLoop);
+ RemoveUnneededFlows(iter->second, Multiple->Next, Multiple->Breaks ? NULL : LastLoop, Depth+1);
}
Next = Multiple->Next;
}, {
- RemoveUnneededFlows(Loop->Inner, Loop->Inner, Loop);
+ RemoveUnneededFlows(Loop->Inner, Loop->Inner, Loop, Depth+1);
Next = Loop->Next;
});
}
diff --git a/src/relooper/fuzzer.py b/src/relooper/fuzzer.py
index 18db997e..156adb76 100644
--- a/src/relooper/fuzzer.py
+++ b/src/relooper/fuzzer.py
@@ -123,14 +123,14 @@ int main() {
open('fuzz.slow.js', 'w').write(slow)
open('fuzz.cpp', 'w').write(fast)
print '_'
- slow_out = subprocess.Popen(['mozjs', '-m', '-n', 'fuzz.slow.js'], stdout=subprocess.PIPE).communicate()[0]
+ slow_out = subprocess.Popen(['mozjs', 'fuzz.slow.js'], stdout=subprocess.PIPE).communicate()[0]
print '.'
subprocess.call(['g++', 'fuzz.cpp', 'Relooper.o', '-o', 'fuzz', '-g'])
print '*'
subprocess.call(['./fuzz'], stdout=open('fuzz.fast.js', 'w'))
print '-'
- fast_out = subprocess.Popen(['mozjs', '-m', '-n', 'fuzz.fast.js'], stdout=subprocess.PIPE).communicate()[0]
+ fast_out = subprocess.Popen(['mozjs', 'fuzz.fast.js'], stdout=subprocess.PIPE).communicate()[0]
print
if slow_out != fast_out:
diff --git a/src/relooper/test.cpp b/src/relooper/test.cpp
index 9f3ddceb..f319757b 100644
--- a/src/relooper/test.cpp
+++ b/src/relooper/test.cpp
@@ -1,4 +1,6 @@
+#include <vector>
+
#include "Relooper.h"
int main() {
@@ -435,5 +437,34 @@ int main() {
puts(r.GetOutputBuffer());
}
+
+ if (1) {
+ Relooper::MakeOutputBuffer(10);
+
+ printf("\n\n-- lots of exits to an unwind block, possible nesting --\n\n");
+
+ const int DEPTH = 40;
+
+ std::vector<Block*> blocks;
+ for (int i = 0; i < DEPTH; i++) blocks.push_back(new Block("// block\n", NULL));
+ Block *last = new Block("// last\nreturn;\n", NULL);
+ Block *UW = new Block("// UW\nresumeException();\n\n", NULL);
+
+ for (int i = 0; i < DEPTH; i++) {
+ Block *b = blocks[i];
+ b->AddBranchTo(i+1 < DEPTH ? blocks[i+1] : last, "check()", NULL);
+ b->AddBranchTo(UW, NULL, NULL);
+ }
+
+ Relooper r;
+ for (int i = 0; i < DEPTH; i++) r.AddBlock(blocks[i]);
+ r.AddBlock(last);
+ r.AddBlock(UW);
+
+ r.Calculate(blocks[0]);
+ r.Render();
+
+ puts(r.GetOutputBuffer());
+ }
}
diff --git a/src/relooper/test.txt b/src/relooper/test.txt
index d53aeeb1..2ae331c0 100644
--- a/src/relooper/test.txt
+++ b/src/relooper/test.txt
@@ -417,3 +417,156 @@
}
// block D
+
+
+-- lots of exits to an unwind block, possible nesting --
+
+ // block
+ do {
+ if (check()) {
+ // block
+ if (check()) {
+ // block
+ if (check()) {
+ // block
+ if (check()) {
+ // block
+ if (check()) {
+ // block
+ if (check()) {
+ // block
+ if (check()) {
+ // block
+ if (check()) {
+ // block
+ if (check()) {
+ // block
+ if (check()) {
+ // block
+ if (check()) {
+ // block
+ if (check()) {
+ // block
+ if (check()) {
+ // block
+ if (check()) {
+ // block
+ if (check()) {
+ // block
+ if (check()) {
+ // block
+ if (check()) {
+ // block
+ if (check()) {
+ // block
+ if (check()) {
+ // block
+ if (!(check())) {
+ break;
+ }
+ // block
+ if (!(check())) {
+ break;
+ }
+ // block
+ if (!(check())) {
+ break;
+ }
+ // block
+ if (!(check())) {
+ break;
+ }
+ // block
+ if (!(check())) {
+ break;
+ }
+ // block
+ if (!(check())) {
+ break;
+ }
+ // block
+ if (!(check())) {
+ break;
+ }
+ // block
+ if (!(check())) {
+ break;
+ }
+ // block
+ if (!(check())) {
+ break;
+ }
+ // block
+ if (!(check())) {
+ break;
+ }
+ // block
+ if (!(check())) {
+ break;
+ }
+ // block
+ if (!(check())) {
+ break;
+ }
+ // block
+ if (!(check())) {
+ break;
+ }
+ // block
+ if (!(check())) {
+ break;
+ }
+ // block
+ if (!(check())) {
+ break;
+ }
+ // block
+ if (!(check())) {
+ break;
+ }
+ // block
+ if (!(check())) {
+ break;
+ }
+ // block
+ if (!(check())) {
+ break;
+ }
+ // block
+ if (!(check())) {
+ break;
+ }
+ // block
+ if (!(check())) {
+ break;
+ }
+ // block
+ if (!(check())) {
+ break;
+ }
+ // last
+ return;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } while(0);
+ // UW
+ resumeException();
+
+
diff --git a/tests/life.c b/tests/life.c
index 4ce8d385..263fa0e6 100644
--- a/tests/life.c
+++ b/tests/life.c
@@ -67,7 +67,9 @@ void game(int w, int h, int i)
i--;
nudge(univ, w, h); // keep it interesting for benchmark
} else {
+#if !__EMSCRIPTEN__
usleep(20000);
+#endif
show(univ, w, h);
}
}