aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2013-08-16 17:02:43 -0700
committerAlon Zakai <alonzakai@gmail.com>2013-08-21 17:09:16 -0700
commitd705c37e34ad11b01ad33e7c985818a14623dff7 (patch)
treebb1a48ff1208f5a4efda08d6f2a5c1827e55a0b3
parentab506b38dbb9acb2db4f1a1b8c1608cc57409a6b (diff)
emit switches in relooper1.5.6
-rw-r--r--src/jsifier.js13
-rw-r--r--src/relooper/Relooper.cpp84
-rw-r--r--src/relooper/Relooper.h5
-rw-r--r--src/relooper/emscripten/glue.js11
-rw-r--r--src/relooper/fuzzer.py29
-rw-r--r--src/relooper/test.cpp100
-rw-r--r--src/relooper/test.txt177
-rw-r--r--src/relooper/test2.c26
-rw-r--r--src/relooper/test2.txt20
-rw-r--r--src/relooper/test3.c14
-rw-r--r--src/relooper/test3.txt43
-rw-r--r--src/relooper/test4.cpp14
-rw-r--r--src/relooper/test4.txt35
-rw-r--r--src/relooper/test5.cpp12
-rw-r--r--src/relooper/test5.txt44
-rw-r--r--src/relooper/test6.cpp8
-rw-r--r--src/relooper/test6.txt20
-rw-r--r--src/relooper/test_dead.cpp4
-rw-r--r--src/relooper/test_debug.cpp8
-rw-r--r--src/relooper/test_debug.txt20
-rw-r--r--src/relooper/test_fuzz1.cpp18
-rw-r--r--src/relooper/test_fuzz1.txt50
-rw-r--r--src/relooper/test_fuzz2.cpp8
-rw-r--r--src/relooper/test_fuzz2.txt19
-rw-r--r--src/relooper/test_fuzz3.cpp10
-rw-r--r--src/relooper/test_fuzz3.txt16
-rw-r--r--src/relooper/test_fuzz4.cpp10
-rw-r--r--src/relooper/test_fuzz4.txt28
-rw-r--r--src/relooper/test_fuzz5.cpp20
-rw-r--r--src/relooper/test_fuzz5.txt64
-rw-r--r--src/relooper/test_fuzz6.cpp184
-rw-r--r--src/relooper/test_fuzz6.txt219
-rw-r--r--src/relooper/test_inf.cpp368
-rw-r--r--src/relooper/test_inf.txt1410
-rw-r--r--tools/shared.py2
35 files changed, 2234 insertions, 879 deletions
diff --git a/src/jsifier.js b/src/jsifier.js
index 683b1874..31e066ab 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -795,7 +795,13 @@ function JSify(data, functionsOnly, givenFunctions) {
var label = block.labels[i];
var content = getLabelLines(label, '', true);
//printErr(func.ident + ' : ' + label.ident + ' : ' + content + '\n');
- blockMap[label.ident] = Relooper.addBlock(content);
+ var last = label.lines[label.lines.length-1];
+ if (last.intertype != 'switch') {
+ blockMap[label.ident] = Relooper.addBlock(content);
+ } else {
+ assert(last.signedIdent);
+ blockMap[label.ident] = Relooper.addBlock(content, last.signedIdent);
+ }
}
// add branchings
function relevant(x) { return x && x.length > 2 ? x : 0 } // ignores ';' which valueJS and label*JS can be if empty
@@ -1125,7 +1131,7 @@ function JSify(data, functionsOnly, givenFunctions) {
}
});
makeFuncLineActor('switch', function(item) {
- var useIfs = RELOOP || item.switchLabels.length < 1024; // with a huge number of cases, if-else which looks nested to js parsers can cause problems
+ var useIfs = false;
var phiSets = calcPhiSets(item);
// Consolidate checks that go to the same label. This is important because it makes the relooper simpler and faster.
var targetLabels = {}; // for each target label, the list of values going to it
@@ -1139,7 +1145,8 @@ function JSify(data, functionsOnly, givenFunctions) {
});
var ret = '';
var first = true;
- var signedIdent = makeSignOp(item.ident, item.type, 're'); // we need to standardize for purpose of comparison
+ signedIdent = makeSignOp(item.ident, item.type, 're'); // we need to standardize for purpose of comparison
+ if (!useIfs) item.signedIdent = signedIdent;
if (RELOOP) {
item.groupedLabels = [];
}
diff --git a/src/relooper/Relooper.cpp b/src/relooper/Relooper.cpp
index a457914b..aefcad93 100644
--- a/src/relooper/Relooper.cpp
+++ b/src/relooper/Relooper.cpp
@@ -104,12 +104,14 @@ void Branch::Render(Block *Target, bool SetLabel) {
int Block::IdCounter = 1; // 0 is reserved for clearings
-Block::Block(const char *CodeInit) : Parent(NULL), Id(Block::IdCounter++), IsCheckedMultipleEntry(false) {
+Block::Block(const char *CodeInit, const char *BranchVarInit) : Parent(NULL), Id(Block::IdCounter++), IsCheckedMultipleEntry(false) {
Code = strdup(CodeInit);
+ BranchVar = BranchVarInit ? strdup(BranchVarInit) : NULL;
}
Block::~Block() {
if (Code) free((void*)Code);
+ if (BranchVar) free((void*)BranchVar);
for (BlockBranchMap::iterator iter = ProcessedBranchesOut.begin(); iter != ProcessedBranchesOut.end(); iter++) {
delete iter->second;
}
@@ -189,8 +191,16 @@ void Block::Render(bool InLoop) {
}
assert(DefaultTarget); // Since each block *must* branch somewhere, this must be set
+ if (ProcessedBranchesOut.size() > 2) assert(BranchVar); // must have a branch variable if multiple conditions
+
+ bool useSwitch = BranchVar != NULL;
+
+ if (useSwitch) {
+ PrintIndented("switch (%s) {\n", BranchVar);
+ }
+
ministring RemainingConditions;
- bool First = true;
+ bool First = !useSwitch; // when using a switch, there is no special first
for (BlockBranchMap::iterator iter = ProcessedBranchesOut.begin();; iter++) {
Block *Target;
Branch *Details;
@@ -208,26 +218,39 @@ void Block::Render(bool InLoop) {
bool HasContent = SetCurrLabel || Details->Type != Branch::Direct || HasFusedContent || Details->Code;
if (iter != ProcessedBranchesOut.end()) {
// If there is nothing to show in this branch, omit the condition
- if (HasContent) {
- PrintIndented("%sif (%s) {\n", First ? "" : "} else ", Details->Condition);
- First = false;
+ if (useSwitch) {
+ PrintIndented("%s {\n", Details->Condition);
} else {
- if (RemainingConditions.size() > 0) RemainingConditions += " && ";
- RemainingConditions += "!(";
- RemainingConditions += Details->Condition;
- RemainingConditions += ")";
+ if (HasContent) {
+ PrintIndented("%sif (%s) {\n", First ? "" : "} else ", Details->Condition);
+ First = false;
+ } else {
+ if (RemainingConditions.size() > 0) RemainingConditions += " && ";
+ RemainingConditions += "!(";
+ if (BranchVar) {
+ RemainingConditions += BranchVar;
+ RemainingConditions += " == ";
+ }
+ RemainingConditions += Details->Condition;
+ RemainingConditions += ")";
+ }
}
} else {
- if (HasContent) {
- if (RemainingConditions.size() > 0) {
- if (First) {
- PrintIndented("if (%s) {\n", RemainingConditions.c_str());
- First = false;
- } else {
- PrintIndented("} else if (%s) {\n", RemainingConditions.c_str());
+ // this is the default
+ if (useSwitch) {
+ PrintIndented("default: {\n");
+ } else {
+ if (HasContent) {
+ if (RemainingConditions.size() > 0) {
+ if (First) {
+ PrintIndented("if (%s) {\n", RemainingConditions.c_str());
+ First = false;
+ } else {
+ PrintIndented("} else if (%s) {\n", RemainingConditions.c_str());
+ }
+ } else if (!First) {
+ PrintIndented("} else {\n");
}
- } else if (!First) {
- PrintIndented("} else {\n");
}
}
}
@@ -236,7 +259,13 @@ void Block::Render(bool InLoop) {
if (HasFusedContent) {
Fused->InnerMap.find(Target)->second->Render(InLoop);
}
+ if (useSwitch && iter != ProcessedBranchesOut.end()) {
+ PrintIndented("break;\n");
+ }
if (!First) Indenter::Unindent();
+ if (useSwitch) {
+ PrintIndented("}\n");
+ }
if (iter == ProcessedBranchesOut.end()) break;
}
if (!First) PrintIndented("}\n");
@@ -392,7 +421,7 @@ void Relooper::Calculate(Block *Entry) {
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);
+ Block *Split = new Block(Original->Code, Original->BranchVar);
Parent->Blocks.push_back(Split);
PrintDebug(" to %d\n", Split->Id);
Split->BranchesIn.insert(Prior);
@@ -975,6 +1004,8 @@ void Relooper::Calculate(Block *Entry) {
Root = Next;
Next = NULL;
SHAPE_SWITCH(Root, {
+ if (Simple->Inner->BranchVar) LastLoop = NULL; // a switch clears out the loop (TODO: only for breaks, not continue)
+
// If there is a next block, we already know at Simple creation time to make direct branches,
// and we can do nothing more. If there is no next however, then Natural is where we will
// go to by doing nothing, so we can potentially optimize some branches to direct.
@@ -1028,6 +1059,11 @@ void Relooper::Calculate(Block *Entry) {
// If we are fusing a Multiple with a loop into this Simple, then visit it now
if (Fused && Fused->NeedLoop) {
LoopStack.push(Fused);
+ }
+ if (Simple->Inner->BranchVar) {
+ LoopStack.push(NULL); // a switch means breaks are now useless, push a dummy
+ }
+ if (Fused) {
RECURSE_Multiple(Fused, FindLabeledLoops);
}
for (BlockBranchMap::iterator iter = Simple->Inner->ProcessedBranchesOut.begin(); iter != Simple->Inner->ProcessedBranchesOut.end(); iter++) {
@@ -1038,14 +1074,18 @@ void Relooper::Calculate(Block *Entry) {
if (Details->Ancestor != LoopStack.top() && Details->Labeled) {
LabeledShape *Labeled = Shape::IsLabeled(Details->Ancestor);
Labeled->Labeled = true;
- Details->Labeled = true;
} else {
Details->Labeled = false;
}
}
}
+ if (Simple->Inner->BranchVar) {
+ LoopStack.pop();
+ }
if (Fused && Fused->NeedLoop) {
LoopStack.pop();
+ }
+ if (Fused) {
Next = Fused->Next;
} else {
Next = Root->Next;
@@ -1173,8 +1213,8 @@ void rl_set_asm_js_mode(int on) {
Relooper::SetAsmJSMode(on);
}
-void *rl_new_block(const char *text) {
- Block *ret = new Block(text);
+void *rl_new_block(const char *text, const char *branch_var) {
+ Block *ret = new Block(text, branch_var);
#if DEBUG
printf(" void *b%d = rl_new_block(\"// code %d\");\n", ret->Id, ret->Id);
__blockDebugMap__[ret] = ret->Id;
diff --git a/src/relooper/Relooper.h b/src/relooper/Relooper.h
index e54b578c..f3dedf8c 100644
--- a/src/relooper/Relooper.h
+++ b/src/relooper/Relooper.h
@@ -59,9 +59,10 @@ struct Block {
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)
+ const char *BranchVar; // If we have more than one branch out, the variable whose value determines where we go
bool IsCheckedMultipleEntry; // If true, we are a multiple entry, so reaching us requires setting the label variable
- Block(const char *CodeInit);
+ Block(const char *CodeInit, const char *BranchVarInit);
~Block();
void AddBranchTo(Block *Target, const char *Condition, const char *Code=NULL);
@@ -235,7 +236,7 @@ extern "C" {
RELOOPERDLL_API void rl_set_output_buffer(char *buffer, int size);
RELOOPERDLL_API void rl_make_output_buffer(int size);
RELOOPERDLL_API void rl_set_asm_js_mode(int on);
-RELOOPERDLL_API void *rl_new_block(const char *text);
+RELOOPERDLL_API void *rl_new_block(const char *text, const char *branch_var);
RELOOPERDLL_API void rl_delete_block(void *block);
RELOOPERDLL_API void rl_block_add_branch_to(void *from, void *to, const char *condition, const char *code);
RELOOPERDLL_API void *rl_new_relooper();
diff --git a/src/relooper/emscripten/glue.js b/src/relooper/emscripten/glue.js
index 36922185..40ddabec 100644
--- a/src/relooper/emscripten/glue.js
+++ b/src/relooper/emscripten/glue.js
@@ -6,15 +6,22 @@
var TBUFFER_SIZE = 10*1024*1024;
var tbuffer = _malloc(TBUFFER_SIZE);
+ var VBUFFER_SIZE = 256;
+ var vbuffer = _malloc(VBUFFER_SIZE);
+
var RelooperGlue = {};
RelooperGlue['init'] = function() {
this.r = _rl_new_relooper();
},
- RelooperGlue['addBlock'] = function(text) {
+ RelooperGlue['addBlock'] = function(text, branchVar) {
assert(this.r);
assert(text.length+1 < TBUFFER_SIZE);
writeStringToMemory(text, tbuffer);
- var b = _rl_new_block(tbuffer);
+ if (branchVar) {
+ assert(branchVar.length+1 < VBUFFER_SIZE);
+ writeStringToMemory(branchVar, vbuffer);
+ }
+ var b = _rl_new_block(tbuffer, branchVar ? vbuffer : 0);
_rl_relooper_add_block(this.r, b);
return b;
};
diff --git a/src/relooper/fuzzer.py b/src/relooper/fuzzer.py
index 5f6bae3d..50846d10 100644
--- a/src/relooper/fuzzer.py
+++ b/src/relooper/fuzzer.py
@@ -26,13 +26,13 @@ while True:
pass
# parts
- entry = '''print('entry'); var label; var state; var decisions = %s; var index = 0; function check() { if (index == decisions.length) throw 'HALT'; return decisions[index++] }''' % str(decisions)
+ entry = '''print('entry'); var label; var state; var modded; var decisions = %s; var index = 0; function check() { if (index == decisions.length) throw 'HALT'; return decisions[index++] }''' % str(decisions)
slow = entry + '\n'
for i in range(len(branches[0])):
if i > 0: slow += 'else '
b = branches[0]
- slow += 'if (state %% %d == %d) { label = %d; }\n' % (len(b)+1, i, b[i]) # TODO: split range 1-n into these options
+ slow += 'if (modded == %d) { label = %d; }\n' % (i, b[i]) # TODO: split range 1-n into these options
if len(branches[0]): slow += 'else '
slow += 'label = %d;\n' % defaults[0]
@@ -51,26 +51,35 @@ int main() {
'''
for i in range(1, num):
- slow += ' case %d: print(%d); state = check(); \n' % (i, i)
+ slow += ' case %d: print(%d); state = check(); modded = state %% %d\n' % (i, i, len(branches[i])+1)
b = branches[i]
for j in range(len(b)):
- slow += ' if (state %% %d == %d) { label = %d; break }\n' % (len(b)+1, j, b[j]) # TODO: split range 1-n into these options
+ slow += ' if (modded == %d) { label = %d; break }\n' % (j, b[j]) # TODO: split range 1-n into these options
slow += ' label = %d; break\n' % defaults[i]
+ branch_vars = []
for i in range(num):
+ branch_var = '"modded"' if len(branches[i]) > 0 and not (len(branches[i]) == 1 and random.random() < 0.5) else 'NULL'
+ branch_vars.append(branch_var)
+
if i == 0:
fast += '''
- Block *b%d = new Block("%s");
-''' % (i, entry)
+ Block *b%d = new Block("%s", %s);
+''' % (i, entry, branch_var)
else:
- fast += ''' Block *b%d = new Block("print(%d); state = check();%s");
-''' % (i, i, '// ' + ('.' * int(random.expovariate(0.5/num))))
+ fast += ''' Block *b%d = new Block("print(%d); state = check(); modded = state %% %d; %s", %s);
+''' % (i, i, len(branches[i])+1, '// ' + ('.' * int(random.expovariate(0.5/num))), branch_var)
for i in range(num):
+ branch_var = branch_vars[i]
b = branches[i]
for j in range(len(b)):
- fast += ''' b%d->AddBranchTo(b%d, "state %% %d == %d");
-''' % (i, b[j], len(b)+1, j)
+ if branch_var == 'NULL':
+ fast += ''' b%d->AddBranchTo(b%d, "modded == %d");
+''' % (i, b[j], j)
+ else:
+ fast += ''' b%d->AddBranchTo(b%d, "case %d:");
+''' % (i, b[j], j)
fast += ''' b%d->AddBranchTo(b%d, NULL);
''' % (i, defaults[i])
diff --git a/src/relooper/test.cpp b/src/relooper/test.cpp
index b2d500d7..fbd9c7aa 100644
--- a/src/relooper/test.cpp
+++ b/src/relooper/test.cpp
@@ -7,11 +7,11 @@ int main() {
if (1) {
Relooper::SetOutputBuffer(buffer, sizeof(buffer));
- printf("\n\n-- If pattern --\n\n");
+ printf("\n\n-- If pattern --\n\n", "the_var");
- 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_a = new Block("// block A\n", "the_var");
+ Block *b_b = new Block("// block B\n", "the_var");
+ Block *b_c = new Block("// block C\n", "the_var");
b_a->AddBranchTo(b_b, "check == 10", "atob();");
b_a->AddBranchTo(b_c, NULL, "atoc();");
@@ -24,7 +24,7 @@ int main() {
r.AddBlock(b_c);
r.Calculate(b_a);
- printf("\n\n");
+ printf("\n\n", "the_var");
r.Render();
puts(buffer);
@@ -33,12 +33,12 @@ int main() {
if (1) {
Relooper::SetOutputBuffer(buffer, sizeof(buffer));
- printf("\n\n-- If-else pattern --\n\n");
+ printf("\n\n-- If-else pattern --\n\n", "the_var");
- 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_a = new Block("// block A\n", "the_var");
+ Block *b_b = new Block("// block B\n", "the_var");
+ Block *b_c = new Block("// block C\n", "the_var");
+ Block *b_d = new Block("// block D\n", "the_var");
b_a->AddBranchTo(b_b, "check == 15");
b_a->AddBranchTo(b_c, NULL);
@@ -54,7 +54,7 @@ int main() {
r.AddBlock(b_d);
r.Calculate(b_a);
- printf("\n\n");
+ printf("\n\n", "the_var");
r.Render();
puts(buffer);
@@ -63,11 +63,11 @@ int main() {
if (1) {
Relooper::SetOutputBuffer(buffer, sizeof(buffer));
- printf("\n\n-- Loop + tail pattern --\n\n");
+ printf("\n\n-- Loop + tail pattern --\n\n", "the_var");
- Block *b_a = new Block("// block A\nvar check = maybe();\n");
- Block *b_b = new Block("// block B\n");
- Block *b_c = new Block("// block C\n");
+ Block *b_a = new Block("// block A\nvar check = maybe();\n", "the_var");
+ Block *b_b = new Block("// block B\n", "the_var");
+ Block *b_c = new Block("// block C\n", "the_var");
b_a->AddBranchTo(b_b, NULL);
@@ -80,7 +80,7 @@ int main() {
r.AddBlock(b_c);
r.Calculate(b_a);
- printf("\n\n");
+ printf("\n\n", "the_var");
r.Render();
puts(buffer);
@@ -89,29 +89,29 @@ int main() {
if (1) {
Relooper::SetOutputBuffer(buffer, sizeof(buffer));
- printf("\n\n-- Loop with phi to head \n\n");
+ printf("\n\n-- Loop with phi to head \n\n", "the_var");
void *block_map[10000];
void *rl = rl_new_relooper();
- void *b1 = rl_new_block("// code 1");
+ void *b1 = rl_new_block("// code 1", "the_var");
block_map[1] = b1;
rl_relooper_add_block(rl, block_map[1]);
- void *b2 = rl_new_block("// code 2");
+ void *b2 = rl_new_block("// code 2", "the_var");
block_map[2] = b2;
rl_relooper_add_block(rl, block_map[2]);
- void *b3 = rl_new_block("// code 3");
+ void *b3 = rl_new_block("// code 3", "the_var");
block_map[3] = b3;
rl_relooper_add_block(rl, block_map[3]);
- void *b4 = rl_new_block("// code 4");
+ void *b4 = rl_new_block("// code 4", "the_var");
block_map[4] = b4;
rl_relooper_add_block(rl, block_map[4]);
- void *b5 = rl_new_block("// code 5");
+ void *b5 = rl_new_block("// code 5", "the_var");
block_map[5] = b5;
rl_relooper_add_block(rl, block_map[5]);
- void *b6 = rl_new_block("// code 6");
+ void *b6 = rl_new_block("// code 6", "the_var");
block_map[6] = b6;
rl_relooper_add_block(rl, block_map[6]);
- void *b7 = rl_new_block("// code 7");
+ void *b7 = rl_new_block("// code 7", "the_var");
block_map[7] = b7;
rl_relooper_add_block(rl, block_map[7]);
rl_block_add_branch_to(block_map[1], block_map[2], NULL, "var $i_0 = 0;var $x_0 = 5; ");
@@ -132,13 +132,13 @@ int main() {
if (1) {
Relooper::SetOutputBuffer(buffer, sizeof(buffer));
- printf("\n\n-- phi on split dead ends --\n\n");
+ printf("\n\n-- phi on split dead ends --\n\n", "the_var");
- 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"); // small and splittable!
- Block *b_e = new Block("// block E\n");
+ Block *b_a = new Block("// block A...................................................................................................\n", "the_var");
+ Block *b_b = new Block("// block B...................................................................................................\n", "the_var");
+ Block *b_c = new Block("// block C...................................................................................................\n", "the_var");
+ Block *b_d = new Block("// block D\n", "the_var"); // small and splittable!
+ Block *b_e = new Block("// block E\n", "the_var");
b_a->AddBranchTo(b_b, "chak()", "atob();");
b_a->AddBranchTo(b_c, NULL, "atoc();");
@@ -155,7 +155,7 @@ int main() {
r.AddBlock(b_e);
r.Calculate(b_a);
- printf("\n\n");
+ printf("\n\n", "the_var");
r.Render();
puts(buffer);
@@ -164,12 +164,12 @@ int main() {
if (1) {
Relooper::SetOutputBuffer(buffer, sizeof(buffer));
- printf("\n\n-- Unbalanced with a dead end --\n\n");
+ printf("\n\n-- Unbalanced with a dead end --\n\n", "the_var");
- Block *b_a = new Block("// block A\n");
- Block *b_b = new Block("// block B\n");
- Block *b_c = new Block("return C;\n");
- Block *b_d = new Block("// block D\n");
+ Block *b_a = new Block("// block A\n", "the_var");
+ Block *b_b = new Block("// block B\n", "the_var");
+ Block *b_c = new Block("return C;\n", "the_var");
+ Block *b_d = new Block("// block D\n", "the_var");
b_a->AddBranchTo(b_b, "check == 10");
b_a->AddBranchTo(b_c, NULL); // c is a dead end
@@ -185,7 +185,7 @@ int main() {
r.AddBlock(b_d);
r.Calculate(b_a);
- printf("\n\n");
+ printf("\n\n", "the_var");
r.Render();
puts(buffer);
@@ -194,14 +194,14 @@ int main() {
if (1) {
Relooper::SetOutputBuffer(buffer, sizeof(buffer));
- printf("\n\n-- if (expensive || expensive2) X else Y; Z --\n\n");
+ printf("\n\n-- if (expensive || expensive2) X else Y; Z --\n\n", "the_var");
- 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");
+ Block *b_a = new Block("// block A\n", "the_var");
+ Block *b_b = new Block("// block B\n", "the_var");
+ Block *b_c = new Block("// block C;\n", "the_var");
+ Block *b_d = new Block("// block D\n", "the_var");
+ Block *b_e = new Block("// block E\n", "the_var");
+ Block *b_f = new Block("// block F\n", "the_var");
b_a->AddBranchTo(b_c, "expensive()");
b_a->AddBranchTo(b_b, NULL);
@@ -226,7 +226,7 @@ int main() {
r.AddBlock(b_f);
r.Calculate(b_a);
- printf("\n\n");
+ printf("\n\n", "the_var");
r.Render();
puts(buffer);
@@ -235,11 +235,11 @@ int main() {
if (1) {
Relooper::SetOutputBuffer(buffer, sizeof(buffer));
- printf("\n\n-- conditional loop --\n\n");
+ printf("\n\n-- conditional loop --\n\n", "the_var");
- 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_a = new Block("// block A\n", "the_var");
+ Block *b_b = new Block("// block B\n", "the_var");
+ Block *b_c = new Block("// block C\n", "the_var");
b_a->AddBranchTo(b_b, "shouldLoop()");
b_a->AddBranchTo(b_c, NULL);
@@ -253,7 +253,7 @@ int main() {
r.AddBlock(b_c);
r.Calculate(b_a);
- printf("\n\n");
+ printf("\n\n", "the_var");
r.Render();
puts(buffer);
diff --git a/src/relooper/test.txt b/src/relooper/test.txt
index 6c910846..2c530567 100644
--- a/src/relooper/test.txt
+++ b/src/relooper/test.txt
@@ -5,13 +5,21 @@
// block A
-if (check == 10) {
+switch (the_var) {
+check == 10 {
atob();
// block B
- btoc();
-} else {
+ switch (the_var) {
+ default: {
+ btoc();
+ }
+ }
+ break;
+}
+default: {
atoc();
}
+}
// block C
@@ -21,10 +29,22 @@ if (check == 10) {
// block A
-if (check == 15) {
+switch (the_var) {
+check == 15 {
// block B
-} else {
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+}
+default: {
// block C
+ switch (the_var) {
+ default: {
+ }
+ }
+}
}
// block D
@@ -34,13 +54,22 @@ if (check == 15) {
-while(1) {
+L9: while(1) {
// block A
var check = maybe();
+ switch (the_var) {
+ default: {
+ }
+ }
// block B
- if (!(check == 41)) {
+ switch (the_var) {
+ check == 41 {
break;
}
+ default: {
+ break L9;
+ }
+ }
}
// block C
@@ -49,30 +78,56 @@ while(1) {
-- Loop with phi to head
// code 1
-var $i_0 = 0;var $x_0 = 5;
-while(1) {
+switch (the_var) {
+default: {
+ var $i_0 = 0;var $x_0 = 5;
+}
+}
+L14: while(1) {
// code 2
- if (!($2)) {
+ switch (the_var) {
+ $2 {
+ break;
+ }
+ default: {
var $x_1 = $x_0;
label = 18;
- break;
+ break L14;
+ }
}
// code 3
- if ($6) {
+ switch (the_var) {
+ $6 {
+ break L14;
break;
- } else {
+ }
+ default: {
var $i_0 = $7;var $x_0 = $5;
}
+ }
}
if (label == 18) {
// code 7
}
// code 4
-if ($10) {
+switch (the_var) {
+$10 {
// code 5
+ switch (the_var) {
+ default: {
+ }
+ }
+ break;
+}
+default: {
+}
}
// code 6
-var $x_1 = $13;
+switch (the_var) {
+default: {
+ var $x_1 = $13;
+}
+}
// code 7
@@ -82,17 +137,29 @@ var $x_1 = $13;
// block A...................................................................................................
-if (chak()) {
+switch (the_var) {
+chak() {
atob();
// block B...................................................................................................
- btod();
+ switch (the_var) {
+ default: {
+ btod();
+ }
+ }
// block D
-} else {
+ break;
+}
+default: {
atoc();
// block C...................................................................................................
- ctod2();
+ switch (the_var) {
+ default: {
+ ctod2();
+ }
+ }
// block D
}
+}
@@ -101,12 +168,25 @@ if (chak()) {
// block A
-if (!(check == 10)) {
+switch (the_var) {
+check == 10 {
+ break;
+}
+default: {
return C;
}
+}
while(1) {
// block B
+ switch (the_var) {
+ default: {
+ }
+ }
// block D
+ switch (the_var) {
+ default: {
+ }
+ }
}
@@ -116,24 +196,49 @@ while(1) {
// block A
-do {
- if (expensive()) {
+L37: do {
+ switch (the_var) {
+ expensive() {
label = 33;
- } else {
+ break;
+ }
+ default: {
// block B
- if (expensive2()) {
+ switch (the_var) {
+ expensive2() {
label = 33;
+ break L37;
break;
}
+ default: {
+ }
+ }
// block D
+ switch (the_var) {
+ default: {
+ }
+ }
+ }
}
} while(0);
if (label == 33) {
// block C;
+ switch (the_var) {
+ default: {
+ }
+ }
}
while(1) {
// block E
+ switch (the_var) {
+ default: {
+ }
+ }
// block F
+ switch (the_var) {
+ default: {
+ }
+ }
}
@@