aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xemcc1
-rw-r--r--src/jsifier.js1
-rw-r--r--src/library.js1
-rw-r--r--src/library_gl.js14
-rw-r--r--src/parseTools.js5
-rw-r--r--src/relooper/Relooper.cpp127
-rw-r--r--src/relooper/Relooper.h7
-rw-r--r--src/relooper/fuzzer.py4
-rw-r--r--src/relooper/test.cpp41
-rw-r--r--src/relooper/test.txt27
-rw-r--r--src/relooper/test4.txt1
-rw-r--r--src/relooper/test_debug.txt76
-rw-r--r--src/relooper/test_fuzz1.txt11
-rw-r--r--src/relooper/test_fuzz5.txt24
-rw-r--r--src/relooper/test_fuzz6.txt1
-rwxr-xr-xsrc/relooper/testit.sh2
-rwxr-xr-xsrc/relooper/updateit.sh2
-rw-r--r--tests/cases/fp80_ta2.ll (renamed from tests/cases/fp80.ll)0
-rw-r--r--tests/cases/muli33_ta2.ll (renamed from tests/cases/muli33.ll)0
-rw-r--r--tests/cases/muli33_ta2.txt (renamed from tests/cases/muli33.txt)0
-rw-r--r--tests/cases/philoop_ta2.ll (renamed from tests/cases/philoop.ll)0
-rw-r--r--tests/cases/philoop_ta2.txt (renamed from tests/cases/philoop.txt)0
-rw-r--r--tests/files.cpp3
-rw-r--r--tests/full_es2_sdlproc.c727
-rwxr-xr-xtests/runner.py63
-rw-r--r--tools/shared.py2
26 files changed, 1020 insertions, 120 deletions
diff --git a/emcc b/emcc
index 65dec978..9feba1b1 100755
--- a/emcc
+++ b/emcc
@@ -995,6 +995,7 @@ try:
key, value = change.split('=')
if value[0] == '@':
value = '"@' + os.path.abspath(value[1:]) + '"'
+ value = value.replace('\\\\', '/').replace('\\', '/') # Convert backslash paths to forward slashes on Windows as well, since the JS compiler otherwise needs the backslashes escaped (alternative is to escape all input paths passing to JS, which feels clumsier to read)
exec('shared.Settings.' + key + ' = ' + value)
# Apply effects from settings
diff --git a/src/jsifier.js b/src/jsifier.js
index 77aff895..156fd65d 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -460,6 +460,7 @@ function JSify(data, functionsOnly, givenFunctions) {
} else {
ident = '_' + ident;
}
+ if (VERBOSE) printErr('adding ' + ident + ' and deps ' + deps);
var depsText = (deps ? '\n' + deps.map(addFromLibrary).filter(function(x) { return x != '' }).join('\n') : '');
var contentText = isFunction ? snippet : ('var ' + ident + '=' + snippet + ';');
if (ASM_JS) {
diff --git a/src/library.js b/src/library.js
index e65754ba..51c4c5cb 100644
--- a/src/library.js
+++ b/src/library.js
@@ -560,6 +560,7 @@ LibraryManager.library = {
var stdout = FS.createDevice(devFolder, 'stdout', null, output);
var stderr = FS.createDevice(devFolder, 'stderr', null, error);
FS.createDevice(devFolder, 'tty', input, output);
+ FS.createDevice(devFolder, 'null', function(){}, function(){});
// Create default streams.
FS.streams[1] = {
diff --git a/src/library_gl.js b/src/library_gl.js
index 5055f9e1..1fa0cc9c 100644
--- a/src/library_gl.js
+++ b/src/library_gl.js
@@ -1280,10 +1280,17 @@ var LibraryGL = {
hasRunInit: false,
init: function() {
+ // Do not activate immediate/emulation code (e.g. replace glDrawElements) when in FULL_ES2 mode.
+ // We do not need full emulation, we instead emulate client-side arrays etc. in FULL_ES2 code in
+ // a straightforward manner, and avoid not having a bound buffer be ambiguous between es2 emulation
+ // code and legacy gl emulation code.
+#if FULL_ES2
+ return;
+#endif
+
if (GLEmulation.hasRunInit) {
return;
}
-
GLEmulation.hasRunInit = true;
GLEmulation.fogColor = new Float32Array(4);
@@ -1983,7 +1990,10 @@ var LibraryGL = {
// GL Immediate mode
+ // See comment in GLEmulation.init()
+#if FULL_ES2 == 0
$GLImmediate__postset: 'GL.immediate.setupFuncs(); Browser.moduleContextCreatedCallbacks.push(function() { GL.immediate.init() });',
+#endif
$GLImmediate__deps: ['$Browser', '$GL', '$GLEmulation'],
$GLImmediate: {
MapTreeLib: null,
@@ -3955,7 +3965,7 @@ var LibraryGL = {
},
// Vertex array object (VAO) support. TODO: when the WebGL extension is popular, use that and remove this code and GL.vaos
- glGenVertexArrays__deps: ['$GLEMulation'],
+ glGenVertexArrays__deps: ['$GLEmulation'],
glGenVertexArrays__sig: 'vii',
glGenVertexArrays: function(n, vaos) {
for (var i = 0; i < n; i++) {
diff --git a/src/parseTools.js b/src/parseTools.js
index 090d85ac..3949491e 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -2047,8 +2047,9 @@ function processMathop(item) {
if ((type == 'i64' || paramTypes[0] == 'i64' || paramTypes[1] == 'i64' || idents[1] == '(i64)' || rawBits > 32) && USE_TYPED_ARRAYS == 2) {
// this code assumes i64 for the most part
- if (ASSERTIONS && rawBits < 64) {
- warnOnce('processMathop processing illegal non-i64 value: ' + [type, paramTypes, idents])
+ if (ASSERTIONS && rawBits > 1 && rawBits < 64) {
+ warnOnce('processMathop processing illegal non-i64 value');
+ if (VERBOSE) printErr([op, item.type, rawBits, type, paramTypes, idents]);
}
var warnI64_1 = function() {
diff --git a/src/relooper/Relooper.cpp b/src/relooper/Relooper.cpp
index 61daed79..8c72b0a6 100644
--- a/src/relooper/Relooper.cpp
+++ b/src/relooper/Relooper.cpp
@@ -104,9 +104,6 @@ Block::Block(const char *CodeInit) : Parent(NULL), Id(Block::IdCounter++), Defau
Block::~Block() {
if (Code) free((void*)Code);
- for (BlockBranchMap::iterator iter = ProcessedBranchesIn.begin(); iter != ProcessedBranchesIn.end(); iter++) {
- delete iter->second;
- }
for (BlockBranchMap::iterator iter = ProcessedBranchesOut.begin(); iter != ProcessedBranchesOut.end(); iter++) {
delete iter->second;
}
@@ -139,10 +136,6 @@ void Block::Render(bool InLoop) {
bool SetLabel = true; // in some cases it is clear we can avoid setting label, see later
- if (ProcessedBranchesOut.size() == 1 && ProcessedBranchesOut.begin()->second->Type == Branch::Direct) {
- SetLabel = false;
- }
-
// A setting of the label variable (label = x) is necessary if it can
// cause an impact. The main case is where we set label to x, then elsewhere
// we check if label is equal to that value, i.e., that label is an entry
@@ -379,22 +372,47 @@ void Relooper::Calculate(Block *Entry) {
Block *Curr = *iter;
TotalCodeSize += strlen(Curr->Code);
}
-
+ BlockSet Splits;
+ BlockSet Removed;
+ //DebugDump(Live, "before");
for (BlockSet::iterator iter = Live.begin(); iter != Live.end(); iter++) {
Block *Original = *iter;
- if (Original->BranchesIn.size() <= 1 || Original->BranchesOut.size() > 0) continue;
+ if (Original->BranchesIn.size() <= 1 || Original->BranchesOut.size() > 0) continue; // only dead ends, for now
+ if (Original->BranchesOut.find(Original) != Original->BranchesOut.end()) continue; // cannot split a looping node
if (strlen(Original->Code)*(Original->BranchesIn.size()-1) > TotalCodeSize/5) continue; // if splitting increases raw code size by a significant amount, abort
// Split the node (for simplicity, we replace all the blocks, even though we could have reused the original)
- for (BlockBranchMap::iterator iter = Original->BranchesIn.begin(); iter != Original->BranchesIn.end(); iter++) {
- Block *Prior = iter->first;
+ PrintDebug("Splitting block %d\n", Original->Id);
+ for (BlockSet::iterator iter = Original->BranchesIn.begin(); iter != Original->BranchesIn.end(); iter++) {
+ Block *Prior = *iter;
Block *Split = new Block(Original->Code);
- Split->BranchesIn[Prior] = new Branch(NULL);
- Prior->BranchesOut[Split] = new Branch(Prior->BranchesOut[Original]->Condition, Prior->BranchesOut[Original]->Code);
+ Parent->Blocks.push_back(Split);
+ PrintDebug(" to %d\n", Split->Id);
+ Split->BranchesIn.insert(Prior);
+ Branch *Details = Prior->BranchesOut[Original];
+ Prior->BranchesOut[Split] = new Branch(Details->Condition, Details->Code);
Prior->BranchesOut.erase(Original);
- Parent->AddBlock(Split);
- Live.insert(Split);
+ for (BlockBranchMap::iterator iter = Original->BranchesOut.begin(); iter != Original->BranchesOut.end(); iter++) {
+ Block *Post = iter->first;
+ Branch *Details = iter->second;
+ Split->BranchesOut[Post] = new Branch(Details->Condition, Details->Code);
+ Post->BranchesIn.insert(Split);
+ }
+ Splits.insert(Split);
+ Removed.insert(Original);
+ }
+ for (BlockBranchMap::iterator iter = Original->BranchesOut.begin(); iter != Original->BranchesOut.end(); iter++) {
+ Block *Post = iter->first;
+ Post->BranchesIn.erase(Original);
}
+ //DebugDump(Live, "mid");
+ }
+ for (BlockSet::iterator iter = Splits.begin(); iter != Splits.end(); iter++) {
+ Live.insert(*iter);
+ }
+ for (BlockSet::iterator iter = Removed.begin(); iter != Removed.end(); iter++) {
+ Live.erase(*iter);
}
+ //DebugDump(Live, "after");
}
};
PreOptimizer Pre(this);
@@ -405,7 +423,7 @@ void Relooper::Calculate(Block *Entry) {
Block *Curr = Blocks[i];
if (Pre.Live.find(Curr) == Pre.Live.end()) continue;
for (BlockBranchMap::iterator iter = Curr->BranchesOut.begin(); iter != Curr->BranchesOut.end(); iter++) {
- iter->first->BranchesIn[Curr] = new Branch(NULL);
+ iter->first->BranchesIn.insert(Curr);
}
}
@@ -435,22 +453,21 @@ void Relooper::Calculate(Block *Entry) {
void Solipsize(Block *Target, Branch::FlowType Type, Shape *Ancestor, BlockSet &From) {
PrintDebug("Solipsizing branches into %d\n", Target->Id);
DebugDump(From, " relevant to solipsize: ");
- for (BlockBranchMap::iterator iter = Target->BranchesIn.begin(); iter != Target->BranchesIn.end();) {
- Block *Prior = iter->first;
+ for (BlockSet::iterator iter = Target->BranchesIn.begin(); iter != Target->BranchesIn.end();) {
+ Block *Prior = *iter;
if (From.find(Prior) == From.end()) {
iter++;
continue;
}
- Branch *TargetIn = iter->second;
Branch *PriorOut = Prior->BranchesOut[Target];
- PriorOut->Ancestor = Ancestor; // Do we need this info
- PriorOut->Type = Type; // on TargetIn too?
+ PriorOut->Ancestor = Ancestor;
+ PriorOut->Type = Type;
if (MultipleShape *Multiple = Shape::IsMultiple(Ancestor)) {
Multiple->NeedLoop++; // We are breaking out of this Multiple, so need a loop
}
iter++; // carefully increment iter before erasing
Target->BranchesIn.erase(Prior);
- Target->ProcessedBranchesIn[Prior] = TargetIn;
+ Target->ProcessedBranchesIn.insert(Prior);
Prior->BranchesOut.erase(Target);
Prior->ProcessedBranchesOut[Target] = PriorOut;
PrintDebug(" eliminated branch from %d\n", Prior->Id);
@@ -488,8 +505,8 @@ void Relooper::Calculate(Block *Entry) {
InnerBlocks.insert(Curr);
Blocks.erase(Curr);
// Add the elements prior to it
- for (BlockBranchMap::iterator iter = Curr->BranchesIn.begin(); iter != Curr->BranchesIn.end(); iter++) {
- Queue.insert(iter->first);
+ for (BlockSet::iterator iter = Curr->BranchesIn.begin(); iter != Curr->BranchesIn.end(); iter++) {
+ Queue.insert(*iter);
}
}
}
@@ -620,8 +637,8 @@ void Relooper::Calculate(Block *Entry) {
BlockList ToInvalidate;
for (BlockSet::iterator iter = CurrGroup.begin(); iter != CurrGroup.end(); iter++) {
Block *Child = *iter;
- for (BlockBranchMap::iterator iter = Child->BranchesIn.begin(); iter != Child->BranchesIn.end(); iter++) {
- Block *Parent = iter->first;
+ for (BlockSet::iterator iter = Child->BranchesIn.begin(); iter != Child->BranchesIn.end(); iter++) {
+ Block *Parent = *iter;
if (Helper.Ownership[Parent] != Helper.Ownership[Child]) {
ToInvalidate.push_back(Child);
}
@@ -751,8 +768,8 @@ void Relooper::Calculate(Block *Entry) {
Block *Entry = iter->first;
BlockSet &Group = iter->second;
BlockBlockSetMap::iterator curr = iter++; // iterate carefully, we may delete
- for (BlockBranchMap::iterator iterBranch = Entry->BranchesIn.begin(); iterBranch != Entry->BranchesIn.end(); iterBranch++) {
- Block *Origin = iterBranch->first;
+ for (BlockSet::iterator iterBranch = Entry->BranchesIn.begin(); iterBranch != Entry->BranchesIn.end(); iterBranch++) {
+ Block *Origin = *iterBranch;
if (Group.find(Origin) == Group.end()) {
// Reached from outside the group, so we cannot handle this
PrintDebug("Cannot handle group with entry %d because of incoming branch from %d\n", Entry->Id, Origin->Id);
@@ -821,13 +838,11 @@ void Relooper::Calculate(Block *Entry) {
// Main
BlockSet AllBlocks;
- for (int i = 0; i < Blocks.size(); i++) {
- AllBlocks.insert(Blocks[i]);
+ for (BlockSet::iterator iter = Pre.Live.begin(); iter != Pre.Live.end(); iter++) {
+ Block *Curr = *iter;
+ AllBlocks.insert(Curr);
#if DEBUG
- PrintDebug("Adding block %d (%s)\n", Blocks[i]->Id, Blocks[i]->Code);
- for (BlockBranchMap::iterator iter = Blocks[i]->BranchesOut.begin(); iter != Blocks[i]->BranchesOut.end(); iter++) {
- PrintDebug(" with branch out to %d\n", iter->first->Id);
- }
+ PrintDebug("Adding block %d (%s)\n", Curr->Id, Curr->Code);
#endif
}
@@ -874,10 +889,26 @@ void Relooper::Calculate(Block *Entry) {
func(Loop->Next); \
}
+ // Find the blocks that natural control flow can get us directly to, or through a multiple that we ignore
+ void FollowNaturalFlow(Shape *S, BlockSet &Out) {
+ SHAPE_SWITCH(S, {
+ Out.insert(Simple->Inner);
+ }, {
+ for (BlockShapeMap::iterator iter = Multiple->InnerMap.begin(); iter != Multiple->InnerMap.end(); iter++) {
+ FollowNaturalFlow(iter->second, Out);
+ }
+ FollowNaturalFlow(Multiple->Next, Out);
+ }, {
+ FollowNaturalFlow(Loop->Inner, Out);
+ });
+ }
+
// 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) {
+ BlockSet NaturalBlocks;
+ FollowNaturalFlow(Natural, NaturalBlocks);
Shape *Next = Root;
while (Next) {
Root = Next;
@@ -892,7 +923,7 @@ void Relooper::Calculate(Block *Entry) {
for (BlockBranchMap::iterator iter = Simple->Inner->ProcessedBranchesOut.begin(); iter != Simple->Inner->ProcessedBranchesOut.end(); iter++) {
Block *Target = iter->first;
Branch *Details = iter->second;
- if (Details->Type != Branch::Direct && Target->Parent == Natural) {
+ if (Details->Type != Branch::Direct && NaturalBlocks.find(Target) != NaturalBlocks.end()) { // note: cannot handle split blocks
Details->Type = Branch::Direct;
if (MultipleShape *Multiple = Shape::IsMultiple(Details->Ancestor)) {
Multiple->NeedLoop--;
@@ -1007,12 +1038,32 @@ void Relooper::SetAsmJSMode(int On) {
#if DEBUG
// Debugging
-void DebugDump(BlockSet &Blocks, const char *prefix) {
+void Debugging::Dump(BlockSet &Blocks, const char *prefix) {
if (prefix) printf("%s ", prefix);
for (BlockSet::iterator iter = Blocks.begin(); iter != Blocks.end(); iter++) {
- printf("%d ", (*iter)->Id);
+ Block *Curr = *iter;
+ printf("%d:\n", Curr->Id);
+ for (BlockBranchMap::iterator iter2 = Curr->BranchesOut.begin(); iter2 != Curr->BranchesOut.end(); iter2++) {
+ Block *Other = iter2->first;
+ printf(" -> %d\n", Other->Id);
+ assert(Other->BranchesIn.find(Curr) != Other->BranchesIn.end());
+ }
}
- printf("\n");
+}
+
+void Debugging::Dump(Shape *S, const char *prefix) {
+ if (prefix) printf("%s ", prefix);
+ printf(" %d ", S->Id);
+ SHAPE_SWITCH(S, {
+ printf("<< Simple with block %d\n", Simple->Inner->Id);
+ }, {
+ printf("<< Multiple\n");
+ for (BlockShapeMap::iterator iter = Multiple->InnerMap.begin(); iter != Multiple->InnerMap.end(); iter++) {
+ printf(" with entry %d\n", iter->first->Id);
+ }
+ }, {
+ printf("<< Loop\n");
+ });
}
static void PrintDebug(const char *Format, ...) {
diff --git a/src/relooper/Relooper.h b/src/relooper/Relooper.h
index eac03738..34b6db08 100644
--- a/src/relooper/Relooper.h
+++ b/src/relooper/Relooper.h
@@ -41,6 +41,7 @@ struct Branch {
void Render(Block *Target, bool SetLabel);
};
+typedef std::set<Block*> BlockSet;
typedef std::map<Block*, Branch*> BlockBranchMap;
// Represents a basic block of code - some instructions that end with a
@@ -52,9 +53,9 @@ struct Block {
// processed branches.
// Blocks own the Branch objects they use, and destroy them when done.
BlockBranchMap BranchesOut;
- BlockBranchMap BranchesIn; // TODO: make this just a list of Incoming, without branch info - should be just on BranchesOut
+ BlockSet BranchesIn;
BlockBranchMap ProcessedBranchesOut;
- BlockBranchMap ProcessedBranchesIn;
+ BlockSet ProcessedBranchesIn;
Shape *Parent; // The shape we are directly inside
int Id; // A unique identifier
const char *Code; // The string representation of the code in this block. Owning pointer (we copy the input)
@@ -205,12 +206,12 @@ struct Relooper {
static void SetAsmJSMode(int On);
};
-typedef std::set<Block*> BlockSet;
typedef std::map<Block*, BlockSet> BlockBlockSetMap;
#if DEBUG
struct Debugging {
static void Dump(BlockSet &Blocks, const char *prefix=NULL);
+ static void Dump(Shape *S, const char *prefix=NULL);
};
#endif
diff --git a/src/relooper/fuzzer.py b/src/relooper/fuzzer.py
index 96929028..5f6bae3d 100644
--- a/src/relooper/fuzzer.py
+++ b/src/relooper/fuzzer.py
@@ -98,14 +98,14 @@ int main() {
open('fuzz.slow.js', 'w').write(slow)
open('fuzz.cpp', 'w').write(fast)
print '_'
- slow_out = subprocess.Popen(['/home/alon/Dev/odinmonkey/js/src/fast/js', '-m', '-n', 'fuzz.slow.js'], stdout=subprocess.PIPE).communicate()[0]
+ slow_out = subprocess.Popen(['mozjs', '-m', '-n', '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(['/home/alon/Dev/odinmonkey/js/src/fast/js', '-m', '-n', 'fuzz.fast.js'], stdout=subprocess.PIPE).communicate()[0]
+ fast_out = subprocess.Popen(['mozjs', '-m', '-n', '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 4275941b..7da990b5 100644
--- a/src/relooper/test.cpp
+++ b/src/relooper/test.cpp
@@ -190,5 +190,46 @@ int main() {
puts(buffer);
}
+
+ if (1) {
+ Relooper::SetOutputBuffer(buffer, sizeof(buffer));
+
+ printf("\n\n-- if (expensive || expensive2) X else Y; Z --\n\n");
+
+ Block *b_a = new Block("// block A\n");
+ Block *b_b = new Block("// block B\n");
+ Block *b_c = new Block("// block C;\n");
+ Block *b_d = new Block("// block D\n");
+ Block *b_e = new Block("// block E\n");
+ Block *b_f = new Block("// block F\n");
+
+ b_a->AddBranchTo(b_c, "expensive()");
+ b_a->AddBranchTo(b_b, NULL);
+
+ b_b->AddBranchTo(b_c, "expensive2()");
+ b_b->AddBranchTo(b_d, NULL);
+
+ b_c->AddBranchTo(b_e, NULL);
+
+ b_d->AddBranchTo(b_e, NULL);
+
+ b_e->AddBranchTo(b_f, NULL);
+
+ b_f->AddBranchTo(b_e, NULL);
+
+ Relooper r;
+ r.AddBlock(b_a);
+ r.AddBlock(b_b);
+ r.AddBlock(b_c);
+ r.AddBlock(b_d);
+ r.AddBlock(b_e);
+ r.AddBlock(b_f);
+
+ r.Calculate(b_a);
+ printf("\n\n");
+ r.Render();
+
+ puts(buffer);
+ }
}
diff --git a/src/relooper/test.txt b/src/relooper/test.txt
index 12d0ef39..d657c6af 100644
--- a/src/relooper/test.txt
+++ b/src/relooper/test.txt
@@ -109,3 +109,30 @@ while(1) {
// block D
}
+
+
+-- if (expensive || expensive2) X else Y; Z --
+
+
+
+// block A
+do {
+ if (expensive()) {
+ label = 33;
+ } else {
+ // block B
+ if (expensive2()) {
+ label = 33;
+ break;
+ }
+ // block D
+ }
+} while(0);
+if (label == 33) {
+ // block C;
+}
+while(1) {
+ // block E
+ // block F
+}
+
diff --git a/src/relooper/test4.txt b/src/relooper/test4.txt
index f0bfb972..3427ff18 100644
--- a/src/relooper/test4.txt
+++ b/src/relooper/test4.txt
@@ -7,7 +7,6 @@ do {
break;
}
//21
- break;
} else {
label = 4;
}
diff --git a/src/relooper/test_debug.txt b/src/relooper/test_debug.txt
index 1c7d0508..d18ed875 100644
--- a/src/relooper/test_debug.txt
+++ b/src/relooper/test_debug.txt
@@ -28,56 +28,88 @@ int main() {
return 0;
}
// Adding block 1 (ep)
-// with branch out to 2
-// with branch out to 4
// Adding block 2 (LBB1)
-// with branch out to 3
-// with branch out to 4
// Adding block 3 (LBB2)
-// with branch out to 4
// Adding block 4 (LBB3)
// Process() called
// Process() running
- blocks : 1 2 3 4
- entries: 1
+ blocks : 1:
+ -> 2
+ -> 4
+2:
+ -> 3
+ -> 4
+3:
+ -> 4
+4:
+ entries: 1:
+ -> 2
+ -> 4
// creating simple block with block #1
// Solipsizing branches into 2
- relevant to solipsize: 1
+ relevant to solipsize: 1:
+ -> 2
+ -> 4
// eliminated branch from 1
// Solipsizing branches into 4
- relevant to solipsize: 1
+ relevant to solipsize: 1:
+ -> 4
// eliminated branch from 1
// Process() running
- blocks : 2 3 4
- entries: 2 4
+ blocks : 2:
+ -> 3
+ -> 4
+3:
+ -> 4
+4:
+ entries: 2:
+ -> 3
+ -> 4
+4:
// Investigated independent groups:
- group: 2 3
+ group: 2:
+ -> 3
+ -> 4
+3:
+ -> 4
// Independent groups: 1
// Handleable independent groups: 1
// creating multiple block with 1 inner groups
// multiple group with entry 2:
- 2 3
+ 2:
+ -> 3
+ -> 4
+3:
+ -> 4
// Solipsizing branches into 4
- relevant to solipsize: 2 3
+ relevant to solipsize: 2:
+ -> 3
+ -> 4
+3:
+ -> 4
// eliminated branch from 2
// eliminated branch from 3
// Process() called
// Process() running
- blocks : 2 3
- entries: 2
+ blocks : 2:
+ -> 3
+3:
+ entries: 2:
+ -> 3
// creating simple block with block #2
// Solipsizing branches into 3
- relevant to solipsize: 2
+ relevant to solipsize: 2:
+ -> 3
// eliminated branch from 2
// Process() running
- blocks : 3
- entries: 3
+ blocks : 3:
+ entries: 3:
// creating simple block with block #3
// Process() returning
- remaining blocks after multiple: 4
+ remaining blocks after multiple: 4:
// Process() running
- blocks : 4
- entries: 4
+ blocks : 4:
+ entries: 4:
// creating simple block with block #4
// Process() returning
// === Optimizing shapes ===
diff --git a/src/relooper/test_fuzz1.txt b/src/relooper/test_fuzz1.txt
index 5122257e..b278e240 100644
--- a/src/relooper/test_fuzz1.txt
+++ b/src/relooper/test_fuzz1.txt
@@ -3,13 +3,10 @@
print('entry'); var label; var state; var decisions = [4, 1, 7, 2, 6, 6, 8]; var index = 0; function check() { if (index == decisions.length) throw 'HALT'; return decisions[index++] }
print(5); state = check();
print(6); state = check();
-do {
- if (state == 7) {
- print(7); state = check();
- label = 3;
- break;
- }
-} while(0);
+if (state == 7) {
+ print(7); state = check();
+ label = 3;
+}
L5: while(1) {
if (label == 3) {
label = 0;
diff --git a/src/relooper/test_fuzz5.txt b/src/relooper/test_fuzz5.txt
index 9548205c..29b2dba4 100644
--- a/src/relooper/test_fuzz5.txt
+++ b/src/relooper/test_fuzz5.txt
@@ -3,22 +3,18 @@
print('entry'); var label; var state; var decisions = [133, 98, 134, 143, 162, 187, 130, 87, 91, 49, 102, 47, 9, 132, 179, 176, 157, 25, 64, 161, 57, 107, 16, 167, 185, 45, 191, 180, 23, 131]; var index = 0; function check() { if (index == decisions.length) throw 'HALT'; return decisions[index++] }
L1: while(1) {
print(7); state = check();
- do {
- if (state % 3 == 1) {
- label = 3;
- } else if (state % 3 == 0) {
- print(8); state = check();
- if (state % 2 == 0) {
- label = 5;
- break;
- } else {
- label = 7;
- break;
- }
+ if (state % 3 == 1) {
+ label = 3;
+ } else if (state % 3 == 0) {
+ print(8); state = check();
+ if (state % 2 == 0) {
+ label = 5;
} else {
- break L1;
+ label = 7;
}
- } while(0);
+ } else {
+ break;
+ }
while(1) {
if (label == 3) {
label = 0;
diff --git a/src/relooper/test_fuzz6.txt b/src/relooper/test_fuzz6.txt
index bd45e8fd..d5a5ab7b 100644
--- a/src/relooper/test_fuzz6.txt
+++ b/src/relooper/test_fuzz6.txt
@@ -82,7 +82,6 @@ while(1) {
print(56); state = check();// ....................................................................................................................................................................................................................
print(34); state = check();// ..........................................................................................................................................
label = 74;
- continue;
}
print(62); state = check();// .......................................................................................
}
diff --git a/src/relooper/testit.sh b/src/relooper/testit.sh
index 61e1a2fb..88db35fb 100755
--- a/src/relooper/testit.sh
+++ b/src/relooper/testit.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
echo "test"
./test &> test.out
diff --git a/src/relooper/updateit.sh b/src/relooper/updateit.sh
index 8c434753..da9fa9aa 100755
--- a/src/relooper/updateit.sh
+++ b/src/relooper/updateit.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
./test &> test.txt
./test2 &> test2.txt
./test3 &> test3.txt
diff --git a/tests/cases/fp80.ll b/tests/cases/fp80_ta2.ll
index 7fc0db4a..7fc0db4a 100644
--- a/tests/cases/fp80.ll
+++ b/tests/cases/fp80_ta2.ll
diff --git a/tests/cases/muli33.ll b/tests/cases/muli33_ta2.ll
index b33b04f7..b33b04f7 100644
--- a/tests/cases/muli33.ll
+++ b/tests/cases/muli33_ta2.ll
diff --git a/tests/cases/muli33.txt b/tests/cases/muli33_ta2.txt
index 21e0231f..21e0231f 100644
--- a/tests/cases/muli33.txt
+++ b/tests/cases/muli33_ta2.txt
diff --git a/tests/cases/philoop.ll b/tests/cases/philoop_ta2.ll
index 5036c7ba..5036c7ba 100644
--- a/tests/cases/philoop.ll
+++ b/tests/cases/philoop_ta2.ll
diff --git a/tests/cases/philoop.txt b/tests/cases/philoop_ta2.txt
index d5117fe8..d5117fe8 100644
--- a/tests/cases/philoop.txt
+++ b/tests/cases/philoop_ta2.txt
diff --git a/tests/files.cpp b/tests/files.cpp
index 04baa151..176cdb62 100644
--- a/tests/files.cpp
+++ b/tests/files.cpp
@@ -56,6 +56,9 @@ int main()
fwrite(data, 1, 5, outf);
fclose(outf);
+ FILE *devNull = fopen("/dev/null", "rb");
+ assert(devNull);
+
char data2[10];
FILE *inf = fopen("go.out", "rb");
int num = fread(data2, 1, 10, inf);
diff --git a/tests/full_es2_sdlproc.c b/tests/full_es2_sdlproc.c
new file mode 100644
index 00000000..d9ac072b
--- /dev/null
+++ b/tests/full_es2_sdlproc.c
@@ -0,0 +1,727 @@
+/*
+ * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without