summaryrefslogtreecommitdiff
path: root/test/example
diff options
context:
space:
mode:
Diffstat (limited to 'test/example')
-rw-r--r--test/example/c-api-kitchen-sink.c60
-rw-r--r--test/example/c-api-kitchen-sink.txt64
-rw-r--r--test/example/c-api-kitchen-sink.txt.txt2
-rw-r--r--test/example/c-api-relooper-unreachable-if.cpp48
-rw-r--r--test/example/c-api-unused-mem.cpp4
-rw-r--r--test/example/c-api-unused-mem.txt42
-rw-r--r--test/example/relooper-fuzz.c4
-rw-r--r--test/example/relooper-fuzz1.c5
-rw-r--r--test/example/relooper-fuzz2.c509
-rw-r--r--test/example/relooper-fuzz2.txt202
-rw-r--r--test/example/relooper-merge1.c211
-rw-r--r--test/example/relooper-merge1.txt71
-rw-r--r--test/example/relooper-merge2.c223
-rw-r--r--test/example/relooper-merge2.txt133
-rw-r--r--test/example/relooper-merge3.c210
-rw-r--r--test/example/relooper-merge3.txt109
-rw-r--r--test/example/relooper-merge4.c210
-rw-r--r--test/example/relooper-merge4.txt109
-rw-r--r--test/example/relooper-merge5.c210
-rw-r--r--test/example/relooper-merge5.txt109
20 files changed, 2411 insertions, 124 deletions
diff --git a/test/example/c-api-kitchen-sink.c b/test/example/c-api-kitchen-sink.c
index 0d9aea2ca..9192c24c6 100644
--- a/test/example/c-api-kitchen-sink.c
+++ b/test/example/c-api-kitchen-sink.c
@@ -316,79 +316,79 @@ void test_relooper() {
}
{ // trivial: just one block
- RelooperRef relooper = RelooperCreate();
+ RelooperRef relooper = RelooperCreate(module);
RelooperBlockRef block = RelooperAddBlock(relooper, makeCallCheck(module, 1337));
- BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, block, 0, module);
+ BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, block, 0);
BinaryenFunctionRef sinker = BinaryenAddFunction(module, "just-one-block", v, localTypes, 1, body);
}
{ // two blocks
- RelooperRef relooper = RelooperCreate();
+ RelooperRef relooper = RelooperCreate(module);
RelooperBlockRef block0 = RelooperAddBlock(relooper, makeCallCheck(module, 0));
RelooperBlockRef block1 = RelooperAddBlock(relooper, makeCallCheck(module, 1));
RelooperAddBranch(block0, block1, NULL, NULL); // no condition, no code on branch
- BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, block0, 0, module);
+ BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, block0, 0);
BinaryenFunctionRef sinker = BinaryenAddFunction(module, "two-blocks", v, localTypes, 1, body);
}
{ // two blocks with code between them
- RelooperRef relooper = RelooperCreate();
+ RelooperRef relooper = RelooperCreate(module);
RelooperBlockRef block0 = RelooperAddBlock(relooper, makeCallCheck(module, 0));
RelooperBlockRef block1 = RelooperAddBlock(relooper, makeCallCheck(module, 1));
RelooperAddBranch(block0, block1, NULL, makeDroppedInt32(module, 77)); // code on branch
- BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, block0, 0, module);
+ BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, block0, 0);
BinaryenFunctionRef sinker = BinaryenAddFunction(module, "two-blocks-plus-code", v, localTypes, 1, body);
}
{ // two blocks in a loop
- RelooperRef relooper = RelooperCreate();
+ RelooperRef relooper = RelooperCreate(module);
RelooperBlockRef block0 = RelooperAddBlock(relooper, makeCallCheck(module, 0));
RelooperBlockRef block1 = RelooperAddBlock(relooper, makeCallCheck(module, 1));
RelooperAddBranch(block0, block1, NULL, NULL);
RelooperAddBranch(block1, block0, NULL, NULL);
- BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, block0, 0, module);
+ BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, block0, 0);
BinaryenFunctionRef sinker = BinaryenAddFunction(module, "loop", v, localTypes, 1, body);
}
{ // two blocks in a loop with codes
- RelooperRef relooper = RelooperCreate();
+ RelooperRef relooper = RelooperCreate(module);
RelooperBlockRef block0 = RelooperAddBlock(relooper, makeCallCheck(module, 0));
RelooperBlockRef block1 = RelooperAddBlock(relooper, makeCallCheck(module, 1));
RelooperAddBranch(block0, block1, NULL, makeDroppedInt32(module, 33));
RelooperAddBranch(block1, block0, NULL, makeDroppedInt32(module, -66));
- BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, block0, 0, module);
+ BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, block0, 0);
BinaryenFunctionRef sinker = BinaryenAddFunction(module, "loop-plus-code", v, localTypes, 1, body);
}
{ // split
- RelooperRef relooper = RelooperCreate();
+ RelooperRef relooper = RelooperCreate(module);
RelooperBlockRef block0 = RelooperAddBlock(relooper, makeCallCheck(module, 0));
RelooperBlockRef block1 = RelooperAddBlock(relooper, makeCallCheck(module, 1));
RelooperBlockRef block2 = RelooperAddBlock(relooper, makeCallCheck(module, 2));
RelooperAddBranch(block0, block1, makeInt32(module, 55), NULL);
RelooperAddBranch(block0, block2, NULL, NULL);
- BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, block0, 0, module);
+ BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, block0, 0);
BinaryenFunctionRef sinker = BinaryenAddFunction(module, "split", v, localTypes, 1, body);
}
{ // split + code
- RelooperRef relooper = RelooperCreate();
+ RelooperRef relooper = RelooperCreate(module);
RelooperBlockRef block0 = RelooperAddBlock(relooper, makeCallCheck(module, 0));
RelooperBlockRef block1 = RelooperAddBlock(relooper, makeCallCheck(module, 1));
RelooperBlockRef block2 = RelooperAddBlock(relooper, makeCallCheck(module, 2));
BinaryenExpressionRef temp = makeDroppedInt32(module, 10);
RelooperAddBranch(block0, block1, makeInt32(module, 55), temp);
RelooperAddBranch(block0, block2, NULL, makeDroppedInt32(module, 20));
- BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, block0, 0, module);
+ BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, block0, 0);
BinaryenFunctionRef sinker = BinaryenAddFunction(module, "split-plus-code", v, localTypes, 1, body);
}
{ // if
- RelooperRef relooper = RelooperCreate();
+ RelooperRef relooper = RelooperCreate(module);
RelooperBlockRef block0 = RelooperAddBlock(relooper, makeCallCheck(module, 0));
RelooperBlockRef block1 = RelooperAddBlock(relooper, makeCallCheck(module, 1));
RelooperBlockRef block2 = RelooperAddBlock(relooper, makeCallCheck(module, 2));
RelooperAddBranch(block0, block1, makeInt32(module, 55), NULL);
RelooperAddBranch(block0, block2, NULL, NULL);
RelooperAddBranch(block1, block2, NULL, NULL);
- BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, block0, 0, module);
+ BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, block0, 0);
BinaryenFunctionRef sinker = BinaryenAddFunction(module, "if", v, localTypes, 1, body);
}
{ // if + code
- RelooperRef relooper = RelooperCreate();
+ RelooperRef relooper = RelooperCreate(module);
RelooperBlockRef block0 = RelooperAddBlock(relooper, makeCallCheck(module, 0));
RelooperBlockRef block1 = RelooperAddBlock(relooper, makeCallCheck(module, 1));
RelooperBlockRef block2 = RelooperAddBlock(relooper, makeCallCheck(module, 2));
@@ -396,11 +396,11 @@ void test_relooper() {
RelooperAddBranch(block0, block1, makeInt32(module, 55), temp);
RelooperAddBranch(block0, block2, NULL, makeDroppedInt32(module, -2));
RelooperAddBranch(block1, block2, NULL, makeDroppedInt32(module, -3));
- BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, block0, 0, module);
+ BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, block0, 0);
BinaryenFunctionRef sinker = BinaryenAddFunction(module, "if-plus-code", v, localTypes, 1, body);
}
{ // if-else
- RelooperRef relooper = RelooperCreate();
+ RelooperRef relooper = RelooperCreate(module);
RelooperBlockRef block0 = RelooperAddBlock(relooper, makeCallCheck(module, 0));
RelooperBlockRef block1 = RelooperAddBlock(relooper, makeCallCheck(module, 1));
RelooperBlockRef block2 = RelooperAddBlock(relooper, makeCallCheck(module, 2));
@@ -409,22 +409,22 @@ void test_relooper() {
RelooperAddBranch(block0, block2, NULL, NULL);
RelooperAddBranch(block1, block3, NULL, NULL);
RelooperAddBranch(block2, block3, NULL, NULL);
- BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, block0, 0, module);
+ BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, block0, 0);
BinaryenFunctionRef sinker = BinaryenAddFunction(module, "if-else", v, localTypes, 1, body);
}
{ // loop+tail
- RelooperRef relooper = RelooperCreate();
+ RelooperRef relooper = RelooperCreate(module);
RelooperBlockRef block0 = RelooperAddBlock(relooper, makeCallCheck(module, 0));
RelooperBlockRef block1 = RelooperAddBlock(relooper, makeCallCheck(module, 1));
RelooperBlockRef block2 = RelooperAddBlock(relooper, makeCallCheck(module, 2));
RelooperAddBranch(block0, block1, NULL, NULL);
RelooperAddBranch(block1, block0, makeInt32(module, 10), NULL);
RelooperAddBranch(block1, block2, NULL, NULL);
- BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, block0, 0, module);
+ BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, block0, 0);
BinaryenFunctionRef sinker = BinaryenAddFunction(module, "loop-tail", v, localTypes, 1, body);
}
{ // nontrivial loop + phi to head
- RelooperRef relooper = RelooperCreate();
+ RelooperRef relooper = RelooperCreate(module);
RelooperBlockRef block0 = RelooperAddBlock(relooper, makeCallCheck(module, 0));
RelooperBlockRef block1 = RelooperAddBlock(relooper, makeCallCheck(module, 1));
RelooperBlockRef block2 = RelooperAddBlock(relooper, makeCallCheck(module, 2));
@@ -441,11 +441,11 @@ void test_relooper() {
RelooperAddBranch(block3, block5, NULL, NULL);
RelooperAddBranch(block4, block5, NULL, NULL);
RelooperAddBranch(block5, block6, NULL, makeDroppedInt32(module, 40));
- BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, block0, 0, module);
+ BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, block0, 0);
BinaryenFunctionRef sinker = BinaryenAddFunction(module, "nontrivial-loop-plus-phi-to-head", v, localTypes, 1, body);
}
{ // switch
- RelooperRef relooper = RelooperCreate();
+ RelooperRef relooper = RelooperCreate(module);
BinaryenExpressionRef temp = makeInt32(module, -99);
RelooperBlockRef block0 = RelooperAddBlockWithSwitch(relooper, makeCallCheck(module, 0), temp);
// TODO: this example is not very good, the blocks should end in a |return| as otherwise they
@@ -459,11 +459,11 @@ void test_relooper() {
BinaryenIndex to_block2[] = { 4 };
RelooperAddBranchForSwitch(block0, block2, to_block2, 1, makeDroppedInt32(module, 55));
RelooperAddBranchForSwitch(block0, block3, NULL, 0, NULL);
- BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, block0, 0, module);
+ BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, block0, 0);
BinaryenFunctionRef sinker = BinaryenAddFunction(module, "switch", v, localTypes, 1, body);
}
{ // duff's device
- RelooperRef relooper = RelooperCreate();
+ RelooperRef relooper = RelooperCreate(module);
RelooperBlockRef block0 = RelooperAddBlock(relooper, makeCallCheck(module, 0));
RelooperBlockRef block1 = RelooperAddBlock(relooper, makeCallCheck(module, 1));
RelooperBlockRef block2 = RelooperAddBlock(relooper, makeCallCheck(module, 2));
@@ -471,7 +471,7 @@ void test_relooper() {
RelooperAddBranch(block0, block2, NULL, NULL);
RelooperAddBranch(block1, block2, NULL, NULL);
RelooperAddBranch(block2, block1, NULL, NULL);
- BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, block0, 3, module); // use $3 as the helper var
+ BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, block0, 3); // use $3 as the helper var
BinaryenType localTypes[] = { BinaryenTypeInt32(), BinaryenTypeInt32(), BinaryenTypeInt64(), BinaryenTypeInt32(), BinaryenTypeFloat32(), BinaryenTypeFloat64(), BinaryenTypeInt32() };
BinaryenFunctionRef sinker = BinaryenAddFunction(module, "duffs-device", v, localTypes, sizeof(localTypes)/sizeof(BinaryenType), body);
}
@@ -479,11 +479,11 @@ void test_relooper() {
BinaryenFunctionTypeRef i = BinaryenAddFunctionType(module, "i", BinaryenTypeInt32(), NULL, 0);
{ // return in a block
- RelooperRef relooper = RelooperCreate();
+ RelooperRef relooper = RelooperCreate(module);
BinaryenExpressionRef listList[] = { makeCallCheck(module, 42), BinaryenReturn(module, makeInt32(module, 1337)) };
BinaryenExpressionRef list = BinaryenBlock(module, "the-list", listList, 2, -1);
RelooperBlockRef block = RelooperAddBlock(relooper, list);
- BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, block, 0, module);
+ BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, block, 0);
BinaryenFunctionRef sinker = BinaryenAddFunction(module, "return", i, localTypes, 1, body);
}
diff --git a/test/example/c-api-kitchen-sink.txt b/test/example/c-api-kitchen-sink.txt
index afb004f81..b7ee4b8b7 100644
--- a/test/example/c-api-kitchen-sink.txt
+++ b/test/example/c-api-kitchen-sink.txt
@@ -1025,7 +1025,7 @@ raw:
)
(func $return (; 15 ;) (type $i) (result i32)
(local $0 i32)
- (block $the-list
+ (block
(call $check
(i32.const 42)
)
@@ -1980,19 +1980,19 @@ int main() {
functionTypes[1] = BinaryenAddFunctionType(the_module, "vi", 0, paramTypes, 1);
}
BinaryenAddFunctionImport(the_module, "check", "module", "check", functionTypes[1]);
- the_relooper = RelooperCreate();
+ the_relooper = RelooperCreate(the_module);
expressions[1] = BinaryenConst(the_module, BinaryenLiteralInt32(1337));
{
BinaryenExpressionRef operands[] = { expressions[1] };
expressions[2] = BinaryenCall(the_module, "check", operands, 1, 0);
}
relooperBlocks[0] = RelooperAddBlock(the_relooper, expressions[2]);
- expressions[3] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0, the_module);
+ expressions[3] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0);
{
BinaryenType varTypes[] = { 1 };
functions[0] = BinaryenAddFunction(the_module, "just-one-block", functionTypes[0], varTypes, 1, expressions[3]);
}
- the_relooper = RelooperCreate();
+ the_relooper = RelooperCreate(the_module);
expressions[4] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
{
BinaryenExpressionRef operands[] = { expressions[4] };
@@ -2006,12 +2006,12 @@ int main() {
}
relooperBlocks[1] = RelooperAddBlock(the_relooper, expressions[7]);
RelooperAddBranch(relooperBlocks[0], relooperBlocks[1], expressions[0], expressions[0]);
- expressions[8] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0, the_module);
+ expressions[8] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0);
{
BinaryenType varTypes[] = { 1 };
functions[1] = BinaryenAddFunction(the_module, "two-blocks", functionTypes[0], varTypes, 1, expressions[8]);
}
- the_relooper = RelooperCreate();
+ the_relooper = RelooperCreate(the_module);
expressions[9] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
{
BinaryenExpressionRef operands[] = { expressions[9] };
@@ -2027,12 +2027,12 @@ int main() {
expressions[13] = BinaryenConst(the_module, BinaryenLiteralInt32(77));
expressions[14] = BinaryenDrop(the_module, expressions[13]);
RelooperAddBranch(relooperBlocks[0], relooperBlocks[1], expressions[0], expressions[14]);
- expressions[15] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0, the_module);
+ expressions[15] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0);
{
BinaryenType varTypes[] = { 1 };
functions[2] = BinaryenAddFunction(the_module, "two-blocks-plus-code", functionTypes[0], varTypes, 1, expressions[15]);
}
- the_relooper = RelooperCreate();
+ the_relooper = RelooperCreate(the_module);
expressions[16] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
{
BinaryenExpressionRef operands[] = { expressions[16] };
@@ -2047,12 +2047,12 @@ int main() {
relooperBlocks[1] = RelooperAddBlock(the_relooper, expressions[19]);
RelooperAddBranch(relooperBlocks[0], relooperBlocks[1], expressions[0], expressions[0]);
RelooperAddBranch(relooperBlocks[1], relooperBlocks[0], expressions[0], expressions[0]);
- expressions[20] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0, the_module);
+ expressions[20] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0);
{
BinaryenType varTypes[] = { 1 };
functions[3] = BinaryenAddFunction(the_module, "loop", functionTypes[0], varTypes, 1, expressions[20]);
}
- the_relooper = RelooperCreate();
+ the_relooper = RelooperCreate(the_module);
expressions[21] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
{
BinaryenExpressionRef operands[] = { expressions[21] };
@@ -2071,12 +2071,12 @@ int main() {
expressions[27] = BinaryenConst(the_module, BinaryenLiteralInt32(-66));
expressions[28] = BinaryenDrop(the_module, expressions[27]);
RelooperAddBranch(relooperBlocks[1], relooperBlocks[0], expressions[0], expressions[28]);
- expressions[29] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0, the_module);
+ expressions[29] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0);
{
BinaryenType varTypes[] = { 1 };
functions[4] = BinaryenAddFunction(the_module, "loop-plus-code", functionTypes[0], varTypes, 1, expressions[29]);
}
- the_relooper = RelooperCreate();
+ the_relooper = RelooperCreate(the_module);
expressions[30] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
{
BinaryenExpressionRef operands[] = { expressions[30] };
@@ -2098,12 +2098,12 @@ int main() {
expressions[36] = BinaryenConst(the_module, BinaryenLiteralInt32(55));
RelooperAddBranch(relooperBlocks[0], relooperBlocks[1], expressions[36], expressions[0]);
RelooperAddBranch(relooperBlocks[0], relooperBlocks[2], expressions[0], expressions[0]);
- expressions[37] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0, the_module);
+ expressions[37] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0);
{
BinaryenType varTypes[] = { 1 };
functions[5] = BinaryenAddFunction(the_module, "split", functionTypes[0], varTypes, 1, expressions[37]);
}
- the_relooper = RelooperCreate();
+ the_relooper = RelooperCreate(the_module);
expressions[38] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
{
BinaryenExpressionRef operands[] = { expressions[38] };
@@ -2129,12 +2129,12 @@ int main() {
expressions[47] = BinaryenConst(the_module, BinaryenLiteralInt32(20));
expressions[48] = BinaryenDrop(the_module, expressions[47]);
RelooperAddBranch(relooperBlocks[0], relooperBlocks[2], expressions[0], expressions[48]);
- expressions[49] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0, the_module);
+ expressions[49] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0);
{
BinaryenType varTypes[] = { 1 };
functions[6] = BinaryenAddFunction(the_module, "split-plus-code", functionTypes[0], varTypes, 1, expressions[49]);
}
- the_relooper = RelooperCreate();
+ the_relooper = RelooperCreate(the_module);
expressions[50] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
{
BinaryenExpressionRef operands[] = { expressions[50] };
@@ -2157,12 +2157,12 @@ int main() {
RelooperAddBranch(relooperBlocks[0], relooperBlocks[1], expressions[56], expressions[0]);
RelooperAddBranch(relooperBlocks[0], relooperBlocks[2], expressions[0], expressions[0]);
RelooperAddBranch(relooperBlocks[1], relooperBlocks[2], expressions[0], expressions[0]);
- expressions[57] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0, the_module);
+ expressions[57] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0);
{
BinaryenType varTypes[] = { 1 };
functions[7] = BinaryenAddFunction(the_module, "if", functionTypes[0], varTypes, 1, expressions[57]);
}
- the_relooper = RelooperCreate();
+ the_relooper = RelooperCreate(the_module);
expressions[58] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
{
BinaryenExpressionRef operands[] = { expressions[58] };
@@ -2191,12 +2191,12 @@ int main() {
expressions[69] = BinaryenConst(the_module, BinaryenLiteralInt32(-3));
expressions[70] = BinaryenDrop(the_module, expressions[69]);
RelooperAddBranch(relooperBlocks[1], relooperBlocks[2], expressions[0], expressions[70]);
- expressions[71] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0, the_module);
+ expressions[71] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0);
{
BinaryenType varTypes[] = { 1 };
functions[8] = BinaryenAddFunction(the_module, "if-plus-code", functionTypes[0], varTypes, 1, expressions[71]);
}
- the_relooper = RelooperCreate();
+ the_relooper = RelooperCreate(the_module);
expressions[72] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
{
BinaryenExpressionRef operands[] = { expressions[72] };
@@ -2226,12 +2226,12 @@ int main() {
RelooperAddBranch(relooperBlocks[0], relooperBlocks[2], expressions[0], expressions[0]);
RelooperAddBranch(relooperBlocks[1], relooperBlocks[3], expressions[0], expressions[0]);
RelooperAddBranch(relooperBlocks[2], relooperBlocks[3], expressions[0], expressions[0]);
- expressions[81] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0, the_module);
+ expressions[81] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0);
{
BinaryenType varTypes[] = { 1 };
functions[9] = BinaryenAddFunction(the_module, "if-else", functionTypes[0], varTypes, 1, expressions[81]);
}
- the_relooper = RelooperCreate();
+ the_relooper = RelooperCreate(the_module);
expressions[82] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
{
BinaryenExpressionRef operands[] = { expressions[82] };
@@ -2254,12 +2254,12 @@ int main() {
expressions[88] = BinaryenConst(the_module, BinaryenLiteralInt32(10));
RelooperAddBranch(relooperBlocks[1], relooperBlocks[0], expressions[88], expressions[0]);
RelooperAddBranch(relooperBlocks[1], relooperBlocks[2], expressions[0], expressions[0]);
- expressions[89] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0, the_module);
+ expressions[89] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0);
{
BinaryenType varTypes[] = { 1 };
functions[10] = BinaryenAddFunction(the_module, "loop-tail", functionTypes[0], varTypes, 1, expressions[89]);
}
- the_relooper = RelooperCreate();
+ the_relooper = RelooperCreate(the_module);
expressions[90] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
{
BinaryenExpressionRef operands[] = { expressions[90] };
@@ -2322,12 +2322,12 @@ int main() {
expressions[113] = BinaryenConst(the_module, BinaryenLiteralInt32(40));
expressions[114] = BinaryenDrop(the_module, expressions[113]);
RelooperAddBranch(relooperBlocks[5], relooperBlocks[6], expressions[0], expressions[114]);
- expressions[115] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0, the_module);
+ expressions[115] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0);
{
BinaryenType varTypes[] = { 1 };
functions[11] = BinaryenAddFunction(the_module, "nontrivial-loop-plus-phi-to-head", functionTypes[0], varTypes, 1, expressions[115]);
}
- the_relooper = RelooperCreate();
+ the_relooper = RelooperCreate(the_module);
expressions[116] = BinaryenConst(the_module, BinaryenLiteralInt32(-99));
expressions[117] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
{
@@ -2367,12 +2367,12 @@ int main() {
BinaryenIndex indexes[] = { 0 };
RelooperAddBranchForSwitch(relooperBlocks[0], relooperBlocks[3], indexes, 0, expressions[0]);
}
- expressions[127] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0, the_module);
+ expressions[127] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0);
{
BinaryenType varTypes[] = { 1 };
functions[12] = BinaryenAddFunction(the_module, "switch", functionTypes[0], varTypes, 1, expressions[127]);
}
- the_relooper = RelooperCreate();
+ the_relooper = RelooperCreate(the_module);
expressions[128] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
{
BinaryenExpressionRef operands[] = { expressions[128] };
@@ -2396,7 +2396,7 @@ int main() {
RelooperAddBranch(relooperBlocks[0], relooperBlocks[2], expressions[0], expressions[0]);
RelooperAddBranch(relooperBlocks[1], relooperBlocks[2], expressions[0], expressions[0]);
RelooperAddBranch(relooperBlocks[2], relooperBlocks[1], expressions[0], expressions[0]);
- expressions[135] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 3, the_module);
+ expressions[135] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 3);
{
BinaryenType varTypes[] = { 1, 1, 2, 1, 3, 4, 1 };
functions[13] = BinaryenAddFunction(the_module, "duffs-device", functionTypes[0], varTypes, 7, expressions[135]);
@@ -2405,7 +2405,7 @@ int main() {
BinaryenType paramTypes[] = { 0 };
functionTypes[2] = BinaryenAddFunctionType(the_module, "i", 1, paramTypes, 0);
}
- the_relooper = RelooperCreate();
+ the_relooper = RelooperCreate(the_module);
expressions[136] = BinaryenConst(the_module, BinaryenLiteralInt32(42));
{
BinaryenExpressionRef operands[] = { expressions[136] };
@@ -2418,7 +2418,7 @@ int main() {
expressions[140] = BinaryenBlock(the_module, "the-list", children, 2, BinaryenTypeAuto());
}
relooperBlocks[0] = RelooperAddBlock(the_relooper, expressions[140]);
- expressions[141] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0, the_module);
+ expressions[141] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0);
{
BinaryenType varTypes[] = { 1 };
functions[14] = BinaryenAddFunction(the_module, "return", functionTypes[2], varTypes, 1, expressions[141]);
@@ -2900,7 +2900,7 @@ raw:
)
(func $return (; 15 ;) (type $i) (result i32)
(local $0 i32)
- (block $the-list
+ (block
(call $check
(i32.const 42)
)
diff --git a/test/example/c-api-kitchen-sink.txt.txt b/test/example/c-api-kitchen-sink.txt.txt
index bddf95e79..c2d518020 100644
--- a/test/example/c-api-kitchen-sink.txt.txt
+++ b/test/example/c-api-kitchen-sink.txt.txt
@@ -1008,7 +1008,7 @@
)
(func $return (; 15 ;) (type $i) (result i32)
(local $0 i32)
- (block $the-list
+ (block
(call $check
(i32.const 42)
)
diff --git a/test/example/c-api-relooper-unreachable-if.cpp b/test/example/c-api-relooper-unreachable-if.cpp
index fc3d2d839..cfd802b58 100644
--- a/test/example/c-api-relooper-unreachable-if.cpp
+++ b/test/example/c-api-relooper-unreachable-if.cpp
@@ -18,7 +18,7 @@ int main() {
BinaryenIndex segmentSizes[] = { 0 };
BinaryenSetMemory(the_module, 256, 256, "memory", segments, segmentOffsets, segmentSizes, 0, 0);
}
- the_relooper = RelooperCreate();
+ the_relooper = RelooperCreate(the_module);
expressions[1] = BinaryenGetLocal(the_module, 0, 1);
expressions[2] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
expressions[3] = BinaryenStore(the_module, 4, 0, 0, expressions[2], expressions[1], 1);
@@ -37,13 +37,13 @@ int main() {
expressions[8] = BinaryenSetLocal(the_module, 0, expressions[7]);
relooperBlocks[1] = RelooperAddBlock(the_relooper, expressions[8]);
RelooperAddBranch(relooperBlocks[1], relooperBlocks[0], expressions[0], expressions[0]);
- expressions[9] = RelooperRenderAndDispose(the_relooper, relooperBlocks[1], 1, the_module);
+ expressions[9] = RelooperRenderAndDispose(the_relooper, relooperBlocks[1], 1);
{
BinaryenType varTypes[] = { 1, 1, 2 };
functions[0] = BinaryenAddFunction(the_module, "tinycore::eh_personality", functionTypes[0], varTypes, 3, expressions[9]);
}
BinaryenAddFunctionExport(the_module, "tinycore::eh_personality", "tinycore::eh_personality");
- the_relooper = RelooperCreate();
+ the_relooper = RelooperCreate(the_module);
expressions[10] = BinaryenGetLocal(the_module, 0, 1);
expressions[11] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
expressions[12] = BinaryenStore(the_module, 4, 0, 0, expressions[11], expressions[10], 1);
@@ -58,13 +58,13 @@ int main() {
expressions[17] = BinaryenSetLocal(the_module, 0, expressions[16]);
relooperBlocks[1] = RelooperAddBlock(the_relooper, expressions[17]);
RelooperAddBranch(relooperBlocks[1], relooperBlocks[0], expressions[0], expressions[0]);
- expressions[18] = RelooperRenderAndDispose(the_relooper, relooperBlocks[1], 1, the_module);
+ expressions[18] = RelooperRenderAndDispose(the_relooper, relooperBlocks[1], 1);
{
BinaryenType varTypes[] = { 1, 1, 2 };
functions[1] = BinaryenAddFunction(the_module, "tinycore::eh_unwind_resume", functionTypes[0], varTypes, 3, expressions[18]);
}
BinaryenAddFunctionExport(the_module, "tinycore::eh_unwind_resume", "tinycore::eh_unwind_resume");
- the_relooper = RelooperCreate();
+ the_relooper = RelooperCreate(the_module);
{
BinaryenExpressionRef children[] = { 0 };
expressions[19] = BinaryenBlock(the_module, "bb0", children, 0, BinaryenTypeAuto());
@@ -86,13 +86,13 @@ int main() {
expressions[23] = BinaryenSetLocal(the_module, 0, expressions[22]);
relooperBlocks[2] = RelooperAddBlock(the_relooper, expressions[23]);
RelooperAddBranch(relooperBlocks[2], relooperBlocks[0], expressions[0], expressions[0]);
- expressions[24] = RelooperRenderAndDispose(the_relooper, relooperBlocks[2], 1, the_module);
+ expressions[24] = RelooperRenderAndDispose(the_relooper, relooperBlocks[2], 1);
{
BinaryenType varTypes[] = { 1, 1, 2 };
functions[2] = BinaryenAddFunction(the_module, "tinycore::panic_fmt", functionTypes[1], varTypes, 3, expressions[24]);
}
BinaryenAddFunctionExport(the_module, "tinycore::panic_fmt", "tinycore::panic_fmt");
- the_relooper = RelooperCreate();
+ the_relooper = RelooperCreate(the_module);
expressions[25] = BinaryenGetLocal(the_module, 0, 1);
expressions[26] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
expressions[27] = BinaryenStore(the_module, 4, 0, 0, expressions[26], expressions[25], 1);
@@ -107,13 +107,13 @@ int main() {
expressions[32] = BinaryenSetLocal(the_module, 0, expressions[31]);
relooperBlocks[1] = RelooperAddBlock(the_relooper, expressions[32]);
RelooperAddBranch(relooperBlocks[1], relooperBlocks[0], expressions[0], expressions[0]);
- expressions[33] = RelooperRenderAndDispose(the_relooper, relooperBlocks[1], 1, the_module);
+ expressions[33] = RelooperRenderAndDispose(the_relooper, relooperBlocks[1], 1);
{
BinaryenType varTypes[] = { 1, 1, 2 };
functions[3] = BinaryenAddFunction(the_module, "tinycore::rust_eh_register_frames", functionTypes[0], varTypes, 3, expressions[33]);
}
BinaryenAddFunctionExport(the_module, "tinycore::rust_eh_register_frames", "tinycore::rust_eh_register_frames");
- the_relooper = RelooperCreate();
+ the_relooper = RelooperCreate(the_module);
expressions[34] = BinaryenGetLocal(the_module, 0, 1);
expressions[35] = BinaryenConst(the_module, BinaryenLiteralInt32(0));
expressions[36] = BinaryenStore(the_module, 4, 0, 0, expressions[35], expressions[34], 1);
@@ -128,13 +128,13 @@ int main() {
expressions[41] = BinaryenSetLocal(the_module, 0, expressions[40]);
relooperBlocks[1] = RelooperAddBlock(the_relooper, expressions[41]);
RelooperAddBranch(relooperBlocks[1], relooperBlocks[0], expressions[0], expressions[0]);
- expressions[42] = RelooperRenderAndDispose(the_relooper, relooperBlocks[1], 1, the_module);
+ expressions[42] = RelooperRenderAndDispose(the_relooper, relooperBlocks[1], 1);
{
BinaryenType varTypes[] = { 1, 1, 2 };
functions[4] = BinaryenAddFunction(the_module, "tinycore::rust_eh_unregister_frames", functionTypes[0], varTypes, 3, expressions[42]);
}
BinaryenAddFunctionExport(the_module, "tinycore::rust_eh_unregister_frames", "tinycore::rust_eh_unregister_frames");
- the_relooper = RelooperCreate();
+ the_relooper = RelooperCreate(the_module);
expressions[43] = BinaryenGetLocal(the_module, 0, 1);
expressions[44] = BinaryenSetLocal(the_module, 1, expressions[43]);
expressions[45] = BinaryenGetLocal(the_module, 1, 1);
@@ -173,13 +173,13 @@ int main() {
expressions[57] = BinaryenSetLocal(the_module, 3, expressions[56]);
relooperBlocks[2] = RelooperAddBlock(the_relooper, expressions[57]);
RelooperAddBranch(relooperBlocks[2], relooperBlocks[0], expressions[0], expressions[0]);
- expressions[58] = RelooperRenderAndDispose(the_relooper, relooperBlocks[2], 4, the_module);
+ expressions[58] = RelooperRenderAndDispose(the_relooper, relooperBlocks[2], 4);
{
BinaryenType varTypes[] = { 1, 1, 1, 1, 2 };
functions[5] = BinaryenAddFunction(the_module, "wasm::print_i32", functionTypes[3], varTypes, 5, expressions[58]);
}
BinaryenAddFunctionExport(the_module, "wasm::print_i32", "wasm::print_i32");
- the_relooper = RelooperCreate();
+ the_relooper = RelooperCreate(the_module);
expressions[59] = BinaryenConst(the_module, BinaryenLiteralInt32(1));
expressions[60] = BinaryenSetLocal(the_module, 0, expressions[59]);
expressions[61] = BinaryenGetLocal(the_module, 0, 1);
@@ -242,13 +242,13 @@ int main() {
expressions[103] = BinaryenSetLocal(the_module, 6, expressions[102]);
relooperBlocks[3] = RelooperAddBlock(the_relooper, expressions[103]);
RelooperAddBranch(relooperBlocks[3], relooperBlocks[0], expressions[0], expressions[0]);
- expressions[104] = RelooperRenderAndDispose(the_relooper, relooperBlocks[3], 7, the_module);
+ expressions[104] = RelooperRenderAndDispose(the_relooper, relooperBlocks[3], 7);
{
BinaryenType varTypes[] = { 1, 1, 1, 1, 1, 1, 1, 1, 2 };
functions[6] = BinaryenAddFunction(the_module, "real_main", functionTypes[4], varTypes, 9, expressions[104]);
}
BinaryenAddFunctionExport(the_module, "real_main", "real_main");
- the_relooper = RelooperCreate();
+ the_relooper = RelooperCreate(the_module);
expressions[105] = BinaryenGetLocal(the_module, 0, 1);
expressions[106] = BinaryenSetLocal(the_module, 2, expressions[105]);
{
@@ -333,7 +333,7 @@ int main() {
expressions[155] = BinaryenSetLocal(the_module, 9, expressions[154]);
relooperBlocks[5] = RelooperAddBlock(the_relooper, expressions[155]);
RelooperAddBranch(relooperBlocks[5], relooperBlocks[0], expressions[0], expressions[0]);
- expressions[156] = RelooperRenderAndDispose(the_relooper, relooperBlocks[5], 10, the_module);
+ expressions[156] = RelooperRenderAndDispose(the_relooper, relooperBlocks[5], 10);
{
BinaryenType varTypes[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 2 };
functions[7] = BinaryenAddFunction(the_module, "main", functionTypes[5], varTypes, 10, expressions[156]);
@@ -369,7 +369,7 @@ int main() {
functions[8] = BinaryenAddFunction(the_module, "__wasm_start", functionTypes[6], varTypes, 0, expressions[164]);
}
BinaryenSetStart(the_module, functions[8]);
- the_relooper = RelooperCreate();
+ the_relooper = RelooperCreate(the_module);
expressions[165] = BinaryenGetLocal(the_module, 0, 1);
expressions[166] = BinaryenSetLocal(the_module, 2, expressions[165]);
expressions[167] = BinaryenGetLocal(the_module, 1, 1);
@@ -432,13 +432,13 @@ int main() {
expressions[209] = BinaryenSetLocal(the_module, 8, expressions[208]);
relooperBlocks[3] = RelooperAddBlock(the_relooper, expressions[209]);
RelooperAddBranch(relooperBlocks[3], relooperBlocks[0], expressions[0], expressions[0]);
- expressions[210] = RelooperRenderAndDispose(the_relooper, relooperBlocks[3], 9, the_module);
+ expressions[210] = RelooperRenderAndDispose(the_relooper, relooperBlocks[3], 9);
{
BinaryenType varTypes[] = { 1, 1, 1, 1, 1, 1, 1, 1, 2 };
functions[9] = BinaryenAddFunction(the_module, "_isize_as_tinycore::Add_::add", functionTypes[7], varTypes, 9, expressions[210]);
}
BinaryenAddFunctionExport(the_module, "_isize_as_tinycore::Add_::add", "_isize_as_tinycore::Add_::add");
- the_relooper = RelooperCreate();
+ the_relooper = RelooperCreate(the_module);
expressions[211] = BinaryenGetLocal(the_module, 0, 1);
expressions[212] = BinaryenSetLocal(the_module, 1, expressions[211]);
expressions[213] = BinaryenGetLocal(the_module, 1, 1);
@@ -465,13 +465,13 @@ int main() {
expressions[226] = BinaryenSetLocal(the_module, 4, expressions[225]);
relooperBlocks[1] = RelooperAddBlock(the_relooper, expressions[226]);
RelooperAddBranch(relooperBlocks[1], relooperBlocks[0], expressions[0], expressions[0]);
- expressions[227] = RelooperRenderAndDispose(the_relooper, relooperBlocks[1], 5, the_module);
+ expressions[227] = RelooperRenderAndDispose(the_relooper, relooperBlocks[1], 5);
{
BinaryenType varTypes[] = { 1, 1, 1, 1, 1, 2 };
functions[10] = BinaryenAddFunction(the_module, "_bool_as_tinycore::Not_::not", functionTypes[8], varTypes, 6, expressions[227]);
}
BinaryenAddFunctionExport(the_module, "_bool_as_tinycore::Not_::not", "_bool_as_tinycore::Not_::not");
- the_relooper = RelooperCreate();
+ the_relooper = RelooperCreate(the_module);
expressions[228] = BinaryenGetLocal(the_module, 0, 1);
expressions[229] = BinaryenSetLocal(the_module, 2, expressions[228]);
expressions[230] = BinaryenGetLocal(the_module, 1, 1);
@@ -503,13 +503,13 @@ int main() {
expressions[248] = BinaryenSetLocal(the_module, 7, expressions[247]);
relooperBlocks[1] = RelooperAddBlock(the_relooper, expressions[248]);
RelooperAddBranch(relooperBlocks[1], relooperBlocks[0], expressions[0], expressions[0]);
- expressions[249] = RelooperRenderAndDispose(the_relooper, relooperBlocks[1], 8, the_module);
+ expressions[249] = RelooperRenderAndDispose(the_relooper, relooperBlocks[1], 8);
{
BinaryenType varTypes[] = { 1, 1, 1, 1, 1, 1, 1, 2 };
functions[11] = BinaryenAddFunction(the_module, "_i16_as_tinycore::PartialEq_::eq", functionTypes[9], varTypes, 8, expressions[249]);
}
BinaryenAddFunctionExport(the_module, "_i16_as_tinycore::PartialEq_::eq", "_i16_as_tinycore::PartialEq_::eq");
- the_relooper = RelooperCreate();
+ the_relooper = RelooperCreate(the_module);
expressions[250] = BinaryenGetLocal(the_module, 0, 1);
expressions[251] = BinaryenSetLocal(the_module, 2, expressions[250]);
expressions[252] = BinaryenGetLocal(the_module, 1, 1);
@@ -541,7 +541,7 @@ int main() {
expressions[270] = BinaryenSetLocal(the_module, 7, expressions[269]);
relooperBlocks[1] = RelooperAddBlock(the_relooper, expressions[270]);
RelooperAddBranch(relooperBlocks[1], relooperBlocks[0], expressions[0], expressions[0]);
- expressions[271] = RelooperRenderAndDispose(the_relooper, relooperBlocks[1], 8, the_module);
+ expressions[271] = RelooperRenderAndDispose(the_relooper, relooperBlocks[1], 8);
{
BinaryenType varTypes[] = { 1, 1, 2, 2, 1, 1, 1, 2 };
functions[12] = BinaryenAddFunction(the_module, "_i64_as_tinycore::PartialEq_::eq", functionTypes[10], varTypes, 8, expressions[271]);
diff --git a/test/example/c-api-unused-mem.cpp b/test/example/c-api-unused-mem.cpp
index 868e8b795..1c74b2dfd 100644
--- a/test/example/c-api-unused-mem.cpp
+++ b/test/example/c-api-unused-mem.cpp
@@ -19,7 +19,7 @@ int main() {
BinaryenIndex segmentSizes[] = { 0 };
BinaryenSetMemory(the_module, 256, 256, "memory", segments, segmentOffsets, segmentSizes, 0, 0);
}
- the_relooper = RelooperCreate();
+ the_relooper = RelooperCreate(the_module);
{
BinaryenExpressionRef children[] = { 0 };
expressions[1] = BinaryenBlock(the_module, "bb0", children, 0, BinaryenTypeAuto());
@@ -44,7 +44,7 @@ int main() {
expressions[9] = BinaryenSetLocal(the_module, 0, expressions[8]);
relooperBlocks[2] = RelooperAddBlock(the_relooper, expressions[9]);
RelooperAddBranch(relooperBlocks[2], relooperBlocks[0], expressions[0], expressions[0]);
- expressions[10] = RelooperRenderAndDispose(the_relooper, relooperBlocks[2], 1, the_module);
+ expressions[10] = RelooperRenderAndDispose(the_relooper, relooperBlocks[2], 1);
{
BinaryenType varTypes[] = { 1, 1, 2 };
functions[0] = BinaryenAddFunction(the_module, "main", functionTypes[0], varTypes, 3, expressions[10]);
diff --git a/test/example/c-api-unused-mem.txt b/test/example/c-api-unused-mem.txt
index 6e67735bd..3c2301ace 100644
--- a/test/example/c-api-unused-mem.txt
+++ b/test/example/c-api-unused-mem.txt
@@ -9,32 +9,23 @@
(local $0 i32)
(local $1 i32)
(local $2 i64)
- (block $block$1$break
+ (block $block$2$break
(set_local $0
(i32.load
(i32.const 0)
)
)
(block
- (br $block$1$break)
+ (br $block$2$break)
)
)
(block
- (block $block$2$break
- (block $bb0
- )
- (block
- (br $block$2$break)
- )
- )
(block
- (block $bb1
- (i32.store
- (i32.const 0)
- (get_local $0)
- )
- (return)
+ (i32.store
+ (i32.const 0)
+ (get_local $0)
)
+ (return)
)
)
)
@@ -46,7 +37,7 @@
(call $main)
)
)
-169
+151
(module
(type $0 (func))
(type $1 (func))
@@ -70,22 +61,13 @@
)
(block $label$3
(block $label$4
- (block $label$5
- )
- (block $label$6
- (br $label$4)
- )
- )
- (block $label$7
- (block $label$8
- (i32.store
- (i32.const 0)
- (get_local $0)
- )
- (return)
+ (i32.store
+ (i32.const 0)
+ (get_local $0)
)
- (unreachable)
+ (return)
)
+ (unreachable)
)
)
(func $__wasm_start (; 1 ;) (type $1)
diff --git a/test/example/relooper-fuzz.c b/test/example/relooper-fuzz.c
index 2b8744d5e..606274683 100644
--- a/test/example/relooper-fuzz.c
+++ b/test/example/relooper-fuzz.c
@@ -62,7 +62,7 @@ int main() {
// contents of main() begin here
- RelooperRef relooper = RelooperCreate();
+ RelooperRef relooper = RelooperCreate(module);
RelooperBlockRef b0;
@@ -223,7 +223,7 @@ int main() {
RelooperAddBranch(b8, b4, NULL, NULL);
- BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, b0, 1, module);
+ BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, b0, 1);
int decisions[] = { 89, 12, 78, 149, 118, 179, 127, 80, 21, 34, 119, 98, 38, 29, 36, 147, 13, 55, 166, 16, 143, 52, 130, 150, 176, 91, 34 };
int numDecisions = sizeof(decisions)/sizeof(int);
diff --git a/test/example/relooper-fuzz1.c b/test/example/relooper-fuzz1.c
index 0e8c738cb..495f7c610 100644
--- a/test/example/relooper-fuzz1.c
+++ b/test/example/relooper-fuzz1.c
@@ -74,7 +74,7 @@ int main() {
// contents of main() begin here
- RelooperRef relooper = RelooperCreate();
+ RelooperRef relooper = RelooperCreate(module);
RelooperBlockRef b0;
@@ -285,8 +285,7 @@ int main() {
RelooperAddBranch(b7, b9, NULL, NULL);
- BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, b0, 1,
- module);
+ BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, b0, 1);
int decisions[] = { 67, 131, 49, 36, 112, 161, 62, 166, 16, 88, 176, 152, 161, 194, 117, 180, 60, 166, 55, 183, 150, 73, 196, 143, 76, 182, 97, 140, 126, 3 };
int numDecisions = sizeof(decisions)/sizeof(int);
diff --git a/test/example/relooper-fuzz2.c b/test/example/relooper-fuzz2.c
new file mode 100644
index 000000000..ad687f918
--- /dev/null
+++ b/test/example/relooper-fuzz2.c
@@ -0,0 +1,509 @@
+
+
+#include <assert.h>
+#include <stdio.h>
+
+#include "binaryen-c.h"
+
+// globals: address 4 is index
+// decisions are at address 8+
+
+int main() {
+ BinaryenModuleRef module = BinaryenModuleCreate();
+
+ // check()
+
+ // if the end, halt
+ BinaryenExpressionRef halter = BinaryenIf(module,
+ BinaryenBinary(module,
+ BinaryenGeUInt32(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(4))),
+ BinaryenConst(module, BinaryenLiteralInt32(4 * 27)) // jumps of 4 bytes
+ ),
+ BinaryenUnreachable(module),
+ NULL
+ );
+ // increment index
+ BinaryenExpressionRef incer = BinaryenStore(module,
+ 4, 0, 0,
+ BinaryenConst(module, BinaryenLiteralInt32(4)),
+ BinaryenBinary(module,
+ BinaryenAddInt32(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(4))),
+ BinaryenConst(module, BinaryenLiteralInt32(4))
+ ),
+ BinaryenTypeInt32()
+ );
+
+ // optionally, print the return value
+ BinaryenExpressionRef args[] = {
+ BinaryenBinary(module,
+ BinaryenSubInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(0)),
+ BinaryenLoad(module,
+ 4, 0, 4, 0, BinaryenTypeInt32(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(4)))
+ )
+ )
+ };
+ BinaryenExpressionRef debugger;
+ if (1) debugger = BinaryenCall(module, "print", args, 1,
+ BinaryenTypeNone());
+ else debugger = BinaryenNop(module);
+
+ // return the decision. need to subtract 4 that we just added,
+ // and add 8 since that's where we start, so overall offset 4
+ BinaryenExpressionRef returner = BinaryenLoad(module,
+ 4, 0, 4, 0, BinaryenTypeInt32(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(4)))
+ );
+ BinaryenExpressionRef checkBodyList[] = { halter, incer, debugger,
+ returner };
+ BinaryenExpressionRef checkBody = BinaryenBlock(module,
+ NULL, checkBodyList, sizeof(checkBodyList) / sizeof(BinaryenExpressionRef),
+ BinaryenTypeInt32()
+ );
+ BinaryenFunctionTypeRef i = BinaryenAddFunctionType(module, "i",
+ BinaryenTypeInt32(),
+ NULL, 0);
+ BinaryenAddFunction(module, "check", i, NULL, 0, checkBody);
+
+ // contents of main() begin here
+
+ RelooperRef relooper = RelooperCreate(module);
+
+
+ RelooperBlockRef b0;
+ {
+ BinaryenExpressionRef args[] = {
+ BinaryenConst(module, BinaryenLiteralInt32(0))
+ };
+ BinaryenExpressionRef list[] = {
+ BinaryenCall(module, "print", args, 1, BinaryenTypeNone()),
+ BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0,
+ BinaryenTypeInt32()))
+ };
+
+ b0 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()));
+
+ }
+
+ RelooperBlockRef b1;
+ {
+ BinaryenExpressionRef args[] = {
+ BinaryenConst(module, BinaryenLiteralInt32(0))
+ };
+ BinaryenExpressionRef list[] = {
+ BinaryenCall(module, "print", args, 1, BinaryenTypeNone()),
+ BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0,
+ BinaryenTypeInt32()))
+ };
+
+ b1 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()));
+
+ }
+
+ RelooperBlockRef b2;
+ {
+ BinaryenExpressionRef args[] = {
+ BinaryenConst(module, BinaryenLiteralInt32(0))
+ };
+ BinaryenExpressionRef list[] = {
+ BinaryenCall(module, "print", args, 1, BinaryenTypeNone()),
+ BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0,
+ BinaryenTypeInt32()))
+ };
+
+ b2 = RelooperAddBlockWithSwitch(relooper,
+ BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()),
+ BinaryenBinary(module,
+ BinaryenRemUInt32(),
+ BinaryenGetLocal(module, 0, BinaryenTypeInt32()),
+ BinaryenConst(module, BinaryenLiteralInt32(2))
+ )
+ );
+
+ }
+
+ RelooperBlockRef b3;
+ {
+ BinaryenExpressionRef args[] = {
+ BinaryenConst(module, BinaryenLiteralInt32(0))
+ };
+ BinaryenExpressionRef list[] = {
+ BinaryenCall(module, "print", args, 1, BinaryenTypeNone()),
+ BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0,
+ BinaryenTypeInt32()))
+ };
+
+ b3 = RelooperAddBlockWithSwitch(relooper,
+ BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()),
+ BinaryenBinary(module,
+ BinaryenRemUInt32(),
+ BinaryenGetLocal(module, 0, BinaryenTypeInt32()),
+ BinaryenConst(module, BinaryenLiteralInt32(1))
+ )
+ );
+
+ }
+
+ RelooperBlockRef b4;
+ {
+ BinaryenExpressionRef args[] = {
+ BinaryenConst(module, BinaryenLiteralInt32(4))
+ };
+ BinaryenExpressionRef list[] = {
+ BinaryenCall(module, "print", args, 1, BinaryenTypeNone()),
+ BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0,
+ BinaryenTypeInt32()))
+ };
+
+ b4 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()));
+
+ }
+
+ RelooperBlockRef b5;
+ {
+ BinaryenExpressionRef args[] = {
+ BinaryenConst(module, BinaryenLiteralInt32(0))
+ };
+ BinaryenExpressionRef list[] = {
+ BinaryenCall(module, "print", args, 1, BinaryenTypeNone()),
+ BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0,
+ BinaryenTypeInt32()))
+ };
+
+ b5 = RelooperAddBlockWithSwitch(relooper,
+ BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()),
+ BinaryenBinary(module,
+ BinaryenRemUInt32(),
+ BinaryenGetLocal(module, 0, BinaryenTypeInt32()),
+ BinaryenConst(module, BinaryenLiteralInt32(1))
+ )
+ );
+
+ }
+
+ RelooperBlockRef b6;
+ {
+ BinaryenExpressionRef args[] = {
+ BinaryenConst(module, BinaryenLiteralInt32(6))
+ };
+ BinaryenExpressionRef list[] = {
+ BinaryenCall(module, "print", args, 1, BinaryenTypeNone()),
+ BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0,
+ BinaryenTypeInt32()))
+ };
+
+ b6 = RelooperAddBlockWithSwitch(relooper,
+ BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()),
+ BinaryenBinary(module,
+ BinaryenRemUInt32(),
+ BinaryenGetLocal(module, 0, BinaryenTypeInt32()),
+ BinaryenConst(module, BinaryenLiteralInt32(3))
+ )
+ );
+
+ }
+
+ RelooperBlockRef b7;
+ {
+ BinaryenExpressionRef args[] = {
+ BinaryenConst(module, BinaryenLiteralInt32(0))
+ };
+ BinaryenExpressionRef list[] = {
+ BinaryenCall(module, "print", args, 1, BinaryenTypeNone()),
+ BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0,
+ BinaryenTypeInt32()))
+ };
+
+ b7 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()));
+
+ }
+
+ RelooperBlockRef b8;
+ {
+ BinaryenExpressionRef args[] = {
+ BinaryenConst(module, BinaryenLiteralInt32(0))
+ };
+ BinaryenExpressionRef list[] = {
+ BinaryenCall(module, "print", args, 1, BinaryenTypeNone()),
+ BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0,
+ BinaryenTypeInt32()))
+ };
+
+ b8 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()));
+
+ }
+
+ RelooperAddBranch(b0, b1, NULL,
+ BinaryenStore(module,
+ 4, 0, 0,
+ BinaryenConst(module, BinaryenLiteralInt32(4)),
+ BinaryenBinary(module,
+ BinaryenAddInt32(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(4))),
+ BinaryenConst(module, BinaryenLiteralInt32(4 * 4))
+ ),
+ BinaryenTypeInt32()
+ ));
+
+ RelooperAddBranch(b1, b1, NULL,
+ BinaryenStore(module,
+ 4, 0, 0,
+ BinaryenConst(module, BinaryenLiteralInt32(4)),
+ BinaryenBinary(module,
+ BinaryenAddInt32(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(4))),
+ BinaryenConst(module, BinaryenLiteralInt32(4 * 4))
+ ),
+ BinaryenTypeInt32()
+ ));
+
+ {
+ BinaryenIndex values[] = { 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86 };
+ RelooperAddBranchForSwitch(b2, b7, values,
+ sizeof(values) / sizeof(BinaryenIndex),
+ BinaryenStore(module,
+ 4, 0, 0,
+ BinaryenConst(module, BinaryenLiteralInt32(4)),
+ BinaryenBinary(module,
+ BinaryenAddInt32(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(4))),
+ BinaryenConst(module, BinaryenLiteralInt32(4 * 6))
+ ),
+ BinaryenTypeInt32()
+ ));
+ }
+
+ RelooperAddBranchForSwitch(b2, b4, NULL, 0,
+ BinaryenStore(module,
+ 4, 0, 0,
+ BinaryenConst(module, BinaryenLiteralInt32(4)),
+ BinaryenBinary(module,
+ BinaryenAddInt32(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(4))),
+ BinaryenConst(module, BinaryenLiteralInt32(4 * 4))
+ ),
+ BinaryenTypeInt32()
+ ));
+
+ RelooperAddBranchForSwitch(b3, b6, NULL, 0,
+ BinaryenStore(module,
+ 4, 0, 0,
+ BinaryenConst(module, BinaryenLiteralInt32(4)),
+ BinaryenBinary(module,
+ BinaryenAddInt32(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(4))),
+ BinaryenConst(module, BinaryenLiteralInt32(4 * 5))
+ ),
+ BinaryenTypeInt32()
+ ));
+
+ RelooperAddBranch(b4, b7, BinaryenBinary(module,
+ BinaryenEqInt32(),
+ BinaryenBinary(module,
+ BinaryenRemUInt32(),
+ BinaryenGetLocal(module, 0, BinaryenTypeInt32()),
+ BinaryenConst(module, BinaryenLiteralInt32(2))
+ ),
+ BinaryenConst(module, BinaryenLiteralInt32(0))
+ ),
+ BinaryenStore(module,
+ 4, 0, 0,
+ BinaryenConst(module, BinaryenLiteralInt32(4)),
+ BinaryenBinary(module,
+ BinaryenAddInt32(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(4))),
+ BinaryenConst(module, BinaryenLiteralInt32(4 * 5))
+ ),
+ BinaryenTypeInt32()
+ ));
+
+ RelooperAddBranch(b4, b3, NULL,
+ BinaryenStore(module,
+ 4, 0, 0,
+ BinaryenConst(module, BinaryenLiteralInt32(4)),
+ BinaryenBinary(module,
+ BinaryenAddInt32(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(4))),
+ BinaryenConst(module, BinaryenLiteralInt32(4 * 3))
+ ),
+ BinaryenTypeInt32()
+ ));
+
+ RelooperAddBranchForSwitch(b5, b1, NULL, 0,
+ BinaryenStore(module,
+ 4, 0, 0,
+ BinaryenConst(module, BinaryenLiteralInt32(4)),
+ BinaryenBinary(module,
+ BinaryenAddInt32(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(4))),
+ BinaryenConst(module, BinaryenLiteralInt32(4 * 4))
+ ),
+ BinaryenTypeInt32()
+ ));
+
+ {
+ BinaryenIndex values[] = { 0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75,78,81,84,87,90,93,96,99,102,105,108 };
+ RelooperAddBranchForSwitch(b6, b1, values,
+ sizeof(values) / sizeof(BinaryenIndex),
+ BinaryenStore(module,
+ 4, 0, 0,
+ BinaryenConst(module, BinaryenLiteralInt32(4)),
+ BinaryenBinary(module,
+ BinaryenAddInt32(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(4))),
+ BinaryenConst(module, BinaryenLiteralInt32(4 * 2))
+ ),
+ BinaryenTypeInt32()
+ ));
+ }
+
+ {
+ BinaryenIndex values[] = { 1,4,7,10,13,16,19,22,25,28,31,34,37,40,43,46,49,52,55,58,61,64,67,70,73,76,79,82,85,88,91,94,97,100,103,106,109,112,115,118,121,124,127,130,133,136,139,142,145,148,151,154,157,160 };
+ RelooperAddBranchForSwitch(b6, b7, values,
+ sizeof(values) / sizeof(BinaryenIndex),
+ BinaryenStore(module,
+ 4, 0, 0,
+ BinaryenConst(module, BinaryenLiteralInt32(4)),
+ BinaryenBinary(module,
+ BinaryenAddInt32(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(4))),
+ BinaryenConst(module, BinaryenLiteralInt32(4 * 3))
+ ),
+ BinaryenTypeInt32()
+ ));
+ }
+
+ RelooperAddBranchForSwitch(b6, b2, NULL, 0,
+ BinaryenStore(module,
+ 4, 0, 0,
+ BinaryenConst(module, BinaryenLiteralInt32(4)),
+ BinaryenBinary(module,
+ BinaryenAddInt32(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(4))),
+ BinaryenConst(module, BinaryenLiteralInt32(4 * 3))
+ ),
+ BinaryenTypeInt32()
+ ));
+
+ RelooperAddBranch(b7, b5, BinaryenBinary(module,
+ BinaryenEqInt32(),
+ BinaryenBinary(module,
+ BinaryenRemUInt32(),
+ BinaryenGetLocal(module, 0, BinaryenTypeInt32()),
+ BinaryenConst(module, BinaryenLiteralInt32(2))
+ ),
+ BinaryenConst(module, BinaryenLiteralInt32(0))
+ ),
+ BinaryenStore(module,
+ 4, 0, 0,
+ BinaryenConst(module, BinaryenLiteralInt32(4)),
+ BinaryenBinary(module,
+ BinaryenAddInt32(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(4))),
+ BinaryenConst(module, BinaryenLiteralInt32(4 * 1))
+ ),
+ BinaryenTypeInt32()
+ ));
+
+ RelooperAddBranch(b7, b1, NULL,
+ BinaryenStore(module,
+ 4, 0, 0,
+ BinaryenConst(module, BinaryenLiteralInt32(4)),
+ BinaryenBinary(module,
+ BinaryenAddInt32(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(4))),
+ BinaryenConst(module, BinaryenLiteralInt32(4 * 4))
+ ),
+ BinaryenTypeInt32()
+ ));
+
+ RelooperAddBranch(b8, b8, NULL,
+ BinaryenStore(module,
+ 4, 0, 0,
+ BinaryenConst(module, BinaryenLiteralInt32(4)),
+ BinaryenBinary(module,
+ BinaryenAddInt32(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(4))),
+ BinaryenConst(module, BinaryenLiteralInt32(4 * 2))
+ ),
+ BinaryenTypeInt32()
+ ));
+
+ BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, b0, 1);
+
+ int decisions[] = { 5, 111, 119, 17, 179, 41, 32, 3, 171, 126, 13, 95, 70, 91, 9, 140, 99, 161, 38, 87, 153, 117, 140, 11, 157, 48, 4 };
+ int numDecisions = sizeof(decisions)/sizeof(int);
+
+ // write out all the decisions, then the body of the function
+ BinaryenExpressionRef full[numDecisions + 1];
+
+ {
+ int i;
+ for (i = 0; i < numDecisions; i++) {
+ full[i] = BinaryenStore(module,
+ 4, 0, 0,
+ BinaryenConst(module, BinaryenLiteralInt32(8 + 4 * i)),
+ BinaryenConst(module, BinaryenLiteralInt32(decisions[i])),
+ BinaryenTypeInt32()
+ );
+ }
+ }
+ full[numDecisions] = body;
+ BinaryenExpressionRef all = BinaryenBlock(module, NULL, full,
+ numDecisions + 1,
+ BinaryenTypeNone());
+
+ BinaryenFunctionTypeRef v = BinaryenAddFunctionType(module, "v",
+ BinaryenTypeNone(),
+ NULL, 0);
+ // locals: state, free-for-label
+ BinaryenType localTypes[] = { BinaryenTypeInt32(), BinaryenTypeInt32() };
+ BinaryenFunctionRef theMain = BinaryenAddFunction(module, "main", v,
+ localTypes, 2, all);
+ BinaryenSetStart(module, theMain);
+
+ // import
+
+ BinaryenType iparams[] = { BinaryenTypeInt32() };
+ BinaryenFunctionTypeRef vi = BinaryenAddFunctionType(module, "vi",
+ BinaryenTypeNone(),
+ iparams, 1);
+ BinaryenAddFunctionImport(module, "print", "spectest", "print", vi);
+
+ // memory
+ BinaryenSetMemory(module, 1, 1, "mem", NULL, NULL, NULL, 0, 0);
+
+ // optionally, optimize
+ if (0) BinaryenModuleOptimize(module);
+
+ assert(BinaryenModuleValidate(module));
+
+ // write it out
+
+ BinaryenModulePrint(module);
+
+ BinaryenModuleDispose(module);
+
+ return 0;
+}
diff --git a/test/example/relooper-fuzz2.txt b/test/example/relooper-fuzz2.txt
new file mode 100644
index 000000000..1df9f0a3a
--- /dev/null
+++ b/test/example/relooper-fuzz2.txt
@@ -0,0 +1,202 @@
+(module
+ (type $i (func (result i32)))
+ (type $v (func))
+ (type $vi (func (param i32)))
+ (import "spectest" "print" (func $print (param i32)))
+ (memory $0 1 1)
+ (export "mem" (memory $0))
+ (start $main)
+ (func $check (; 1 ;) (type $i) (result i32)
+ (if
+ (i32.ge_u
+ (i32.load
+ (i32.const 4)
+ )
+ (i32.const 108)
+ )
+ (unreachable)
+ )
+ (i32.store
+ (i32.const 4)
+ (i32.add
+ (i32.load
+ (i32.const 4)
+ )
+ (i32.const 4)
+ )
+ )
+ (call $print
+ (i32.sub
+ (i32.const 0)
+ (i32.load offset=4
+ (i32.load
+ (i32.const 4)
+ )
+ )
+ )
+ )
+ (i32.load offset=4
+ (i32.load
+ (i32.const 4)
+ )
+ )
+ )
+ (func $main (; 2 ;) (type $v)
+ (local $0 i32)
+ (local $1 i32)
+ (i32.store
+ (i32.const 8)
+ (i32.const 5)
+ )
+ (i32.store
+ (i32.const 12)
+ (i32.const 111)
+ )
+ (i32.store
+ (i32.const 16)
+ (i32.const 119)
+ )
+ (i32.store
+ (i32.const 20)
+ (i32.const 17)
+ )
+ (i32.store
+ (i32.const 24)
+ (i32.const 179)
+ )
+ (i32.store
+ (i32.const 28)
+ (i32.const 41)
+ )
+ (i32.store
+ (i32.const 32)
+ (i32.const 32)
+ )
+ (i32.store
+ (i32.const 36)
+ (i32.const 3)
+ )
+ (i32.store
+ (i32.const 40)
+ (i32.const 171)
+ )
+ (i32.store
+ (i32.const 44)
+ (i32.const 126)
+ )
+ (i32.store
+ (i32.const 48)
+ (i32.const 13)
+ )
+ (i32.store
+ (i32.const 52)
+ (i32.const 95)
+ )
+ (i32.store
+ (i32.const 56)
+ (i32.const 70)
+ )
+ (i32.store
+ (i32.const 60)
+ (i32.const 91)
+ )
+ (i32.store
+ (i32.const 64)
+ (i32.const 9)
+ )
+ (i32.store
+ (i32.const 68)
+ (i32.const 140)
+ )
+ (i32.store
+ (i32.const 72)
+ (i32.const 99)
+ )
+ (i32.store
+ (i32.const 76)
+ (i32.const 161)
+ )
+ (i32.store
+ (i32.const 80)
+ (i32.const 38)
+ )
+ (i32.store
+ (i32.const 84)
+ (i32.const 87)
+ )
+ (i32.store
+ (i32.const 88)
+ (i32.const 153)
+ )
+ (i32.store
+ (i32.const 92)
+ (i32.const 117)
+ )
+ (i32.store
+ (i32.const 96)
+ (i32.const 140)
+ )
+ (i32.store
+ (i32.const 100)
+ (i32.const 11)
+ )
+ (i32.store
+ (i32.const 104)
+ (i32.const 157)
+ )
+ (i32.store
+ (i32.const 108)
+ (i32.const 48)
+ )
+ (i32.store
+ (i32.const 112)
+ (i32.const 4)
+ )
+ (block
+ (block $block$2$break
+ (block
+ (call $print
+ (i32.const 0)
+ )
+ (set_local $0
+ (call $check)
+ )
+ )
+ (block
+ (i32.store
+ (i32.const 4)
+ (i32.add
+ (i32.load
+ (i32.const 4)
+ )
+ (i32.const 16)
+ )
+ )
+ (br $block$2$break)
+ )
+ )
+ (loop $shape$1$continue
+ (block
+ (call $print
+ (i32.const 0)
+ )
+ (set_local $0
+ (call $check)
+ )
+ )
+ (block
+ (i32.store
+ (i32.const 4)
+ (i32.add
+ (i32.load
+ (i32.const 4)
+ )
+ (i32.const 16)
+ )
+ )
+ (br $shape$1$continue)
+ )
+ )
+ )
+ )
+)
diff --git a/test/example/relooper-merge1.c b/test/example/relooper-merge1.c
new file mode 100644
index 000000000..9bcc403d5
--- /dev/null
+++ b/test/example/relooper-merge1.c
@@ -0,0 +1,211 @@
+
+
+#include <assert.h>
+#include <stdio.h>
+
+#include "binaryen-c.h"
+
+// globals: address 4 is index
+// decisions are at address 8+
+
+int main() {
+ BinaryenModuleRef module = BinaryenModuleCreate();
+
+ // check()
+
+ // if the end, halt
+ BinaryenExpressionRef halter = BinaryenIf(module,
+ BinaryenBinary(module,
+ BinaryenGeUInt32(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(4))),
+ BinaryenConst(module, BinaryenLiteralInt32(4 * 12)) // jumps of 4 bytes
+ ),
+ BinaryenUnreachable(module),
+ NULL
+ );
+ // increment index
+ BinaryenExpressionRef incer = BinaryenStore(module,
+ 4, 0, 0,
+ BinaryenConst(module, BinaryenLiteralInt32(4)),
+ BinaryenBinary(module,
+ BinaryenAddInt32(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(4))),
+ BinaryenConst(module, BinaryenLiteralInt32(4))
+ ),
+ BinaryenTypeInt32()
+ );
+
+ // optionally, print the return value
+ BinaryenExpressionRef args[] = {
+ BinaryenBinary(module,
+ BinaryenSubInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(0)),
+ BinaryenLoad(module,
+ 4, 0, 4, 0, BinaryenTypeInt32(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(4)))
+ )
+ )
+ };
+ BinaryenExpressionRef debugger;
+ if (1) debugger = BinaryenCall(module, "print", args, 1,
+ BinaryenTypeNone());
+ else debugger = BinaryenNop(module);
+
+ // return the decision. need to subtract 4 that we just added,
+ // and add 8 since that's where we start, so overall offset 4
+ BinaryenExpressionRef returner = BinaryenLoad(module,
+ 4, 0, 4, 0, BinaryenTypeInt32(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(4)))
+ );
+ BinaryenExpressionRef checkBodyList[] = { halter, incer, debugger,
+ returner };
+ BinaryenExpressionRef checkBody = BinaryenBlock(module,
+ NULL, checkBodyList, sizeof(checkBodyList) / sizeof(BinaryenExpressionRef),
+ BinaryenTypeInt32()
+ );
+ BinaryenFunctionTypeRef i = BinaryenAddFunctionType(module, "i",
+ BinaryenTypeInt32(),
+ NULL, 0);
+ BinaryenAddFunction(module, "check", i, NULL, 0, checkBody);
+
+ // contents of main() begin here
+
+ RelooperRef relooper = RelooperCreate(module);
+
+
+ RelooperBlockRef b0;
+ {
+ BinaryenExpressionRef args[] = {
+ BinaryenConst(module, BinaryenLiteralInt32(0))
+ };
+ BinaryenExpressionRef list[] = {
+ BinaryenCall(module, "print", args, 1, BinaryenTypeNone()),
+ BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0,
+ BinaryenTypeInt32()))
+ };
+
+ b0 = RelooperAddBlockWithSwitch(relooper,
+ BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()),
+ BinaryenBinary(module,
+ BinaryenRemUInt32(),
+ BinaryenGetLocal(module, 0, BinaryenTypeInt32()),
+ BinaryenConst(module, BinaryenLiteralInt32(1))
+ )
+ );
+
+ }
+
+ RelooperBlockRef b1;
+ {
+ BinaryenExpressionRef args[] = {
+ BinaryenConst(module, BinaryenLiteralInt32(1))
+ };
+ BinaryenExpressionRef list[] = {
+ BinaryenCall(module, "print", args, 1, BinaryenTypeNone()),
+ BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0,
+ BinaryenTypeInt32()))
+ };
+
+ b1 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()));
+
+ }
+
+ RelooperBlockRef b2;
+ {
+ BinaryenExpressionRef args[] = {
+ BinaryenConst(module, BinaryenLiteralInt32(1))
+ };
+ BinaryenExpressionRef list[] = {
+ BinaryenCall(module, "print", args, 1, BinaryenTypeNone()),
+ BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0,
+ BinaryenTypeInt32()))
+ };
+
+ b2 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()));
+
+ }
+
+ RelooperBlockRef b3;
+ {
+ BinaryenExpressionRef args[] = {
+ BinaryenConst(module, BinaryenLiteralInt32(1))
+ };
+ BinaryenExpressionRef list[] = {
+ BinaryenCall(module, "print", args, 1, BinaryenTypeNone()),
+ BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0,
+ BinaryenTypeInt32()))
+ };
+
+ b3 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()));
+ }
+
+ RelooperBlockRef b4;
+ {
+ BinaryenExpressionRef args[] = {
+ BinaryenConst(module, BinaryenLiteralInt32(1))
+ };
+ BinaryenExpressionRef list[] = {
+ BinaryenCall(module, "print", args, 1, BinaryenTypeNone()),
+ BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0,
+ BinaryenTypeInt32()))
+ };
+
+ b4 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()));
+ }
+
+ // Separate branch for each.
+ // In this testcase, target blocks have identical contents (print 1),
+ // and branches have no phi codes, and no loops.
+ {
+ BinaryenIndex indexes[] = { 1, 4, 9 };
+ RelooperAddBranchForSwitch(b0, b1, indexes, 3, NULL);
+ }
+ {
+ BinaryenIndex indexes[] = { 3, 6 };
+ RelooperAddBranchForSwitch(b0, b2, indexes, 2, NULL);
+ }
+ {
+ BinaryenIndex indexes[] = { 5, 25, 125 };
+ RelooperAddBranchForSwitch(b0, b3, indexes, 3, NULL);
+ }
+ RelooperAddBranchForSwitch(b0, b4, NULL, 0, NULL);
+
+ BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, b0, 1);
+
+ BinaryenFunctionTypeRef v = BinaryenAddFunctionType(module, "v",
+ BinaryenTypeNone(),
+ NULL, 0);
+ // locals: state, free-for-label
+ BinaryenType localTypes[] = { BinaryenTypeInt32(), BinaryenTypeInt32() };
+ BinaryenFunctionRef theMain = BinaryenAddFunction(module, "main", v,
+ localTypes, 2, body);
+ BinaryenSetStart(module, theMain);
+
+ // import
+
+ BinaryenType iparams[] = { BinaryenTypeInt32() };
+ BinaryenFunctionTypeRef vi = BinaryenAddFunctionType(module, "vi",
+ BinaryenTypeNone(),
+ iparams, 1);
+ BinaryenAddFunctionImport(module, "print", "spectest", "print", vi);
+
+ // memory
+ BinaryenSetMemory(module, 1, 1, "mem", NULL, NULL, NULL, 0, 0);
+
+ // optionally, optimize
+ if (0) BinaryenModuleOptimize(module);
+
+ assert(BinaryenModuleValidate(module));
+
+ // write it out
+
+ BinaryenModulePrint(module);
+
+ BinaryenModuleDispose(module);
+
+ return 0;
+}
diff --git a/test/example/relooper-merge1.txt b/test/example/relooper-merge1.txt
new file mode 100644
index 000000000..b6d1f49f1
--- /dev/null
+++ b/test/example/relooper-merge1.txt
@@ -0,0 +1,71 @@
+(module
+ (type $i (func (result i32)))
+ (type $v (func))
+ (type $vi (func (param i32)))
+ (import "spectest" "print" (func $print (param i32)))
+ (memory $0 1 1)
+ (export "mem" (memory $0))
+ (start $main)
+ (func $check (; 1 ;) (type $i) (result i32)
+ (if
+ (i32.ge_u
+ (i32.load
+ (i32.const 4)
+ )
+ (i32.const 48)
+ )
+ (unreachable)
+ )
+ (i32.store
+ (i32.const 4)
+ (i32.add
+ (i32.load
+ (i32.const 4)
+ )
+ (i32.const 4)
+ )
+ )
+ (call $print
+ (i32.sub
+ (i32.const 0)
+ (i32.load offset=4
+ (i32.load
+ (i32.const 4)
+ )
+ )
+ )
+ )
+ (i32.load offset=4
+ (i32.load
+ (i32.const 4)
+ )
+ )
+ )
+ (func $main (; 2 ;) (type $v)
+ (local $0 i32)
+ (local $1 i32)
+ (block $block$2$break
+ (block
+ (call $print
+ (i32.const 0)
+ )
+ (set_local $0
+ (call $check)
+ )
+ )
+ (block
+ (br $block$2$break)
+ )
+ )
+ (block
+ (block
+ (call $print
+ (i32.const 1)
+ )
+ (set_local $0
+ (call $check)
+ )
+ )
+ )
+ )
+)
diff --git a/test/example/relooper-merge2.c b/test/example/relooper-merge2.c
new file mode 100644
index 000000000..852e75842
--- /dev/null
+++ b/test/example/relooper-merge2.c
@@ -0,0 +1,223 @@
+
+
+#include <assert.h>
+#include <stdio.h>
+
+#include "binaryen-c.h"
+
+// globals: address 4 is index
+// decisions are at address 8+
+
+int main() {
+ BinaryenModuleRef module = BinaryenModuleCreate();
+
+ // check()
+
+ // if the end, halt
+ BinaryenExpressionRef halter = BinaryenIf(module,
+ BinaryenBinary(module,
+ BinaryenGeUInt32(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(4))),
+ BinaryenConst(module, BinaryenLiteralInt32(4 * 12)) // jumps of 4 bytes
+ ),
+ BinaryenUnreachable(module),
+ NULL
+ );
+ // increment index
+ BinaryenExpressionRef incer = BinaryenStore(module,
+ 4, 0, 0,
+ BinaryenConst(module, BinaryenLiteralInt32(4)),
+ BinaryenBinary(module,
+ BinaryenAddInt32(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(4))),
+ BinaryenConst(module, BinaryenLiteralInt32(4))
+ ),
+ BinaryenTypeInt32()
+ );
+
+ // optionally, print the return value
+ BinaryenExpressionRef args[] = {
+ BinaryenBinary(module,
+ BinaryenSubInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(0)),
+ BinaryenLoad(module,
+ 4, 0, 4, 0, BinaryenTypeInt32(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(4)))
+ )
+ )
+ };
+ BinaryenExpressionRef debugger;
+ if (1) debugger = BinaryenCall(module, "print", args, 1,
+ BinaryenTypeNone());
+ else debugger = BinaryenNop(module);
+
+ // return the decision. need to subtract 4 that we just added,
+ // and add 8 since that's where we start, so overall offset 4
+ BinaryenExpressionRef returner = BinaryenLoad(module,
+ 4, 0, 4, 0, BinaryenTypeInt32(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(4)))
+ );
+ BinaryenExpressionRef checkBodyList[] = { halter, incer, debugger,
+ returner };
+ BinaryenExpressionRef checkBody = BinaryenBlock(module,
+ NULL, checkBodyList, sizeof(checkBodyList) / sizeof(BinaryenExpressionRef),
+ BinaryenTypeInt32()
+ );
+ BinaryenFunctionTypeRef i = BinaryenAddFunctionType(module, "i",
+ BinaryenTypeInt32(),
+ NULL, 0);
+ BinaryenAddFunction(module, "check", i, NULL, 0, checkBody);
+
+ // contents of main() begin here
+
+ RelooperRef relooper = RelooperCreate(module);
+
+
+ RelooperBlockRef b0;
+ {
+ BinaryenExpressionRef args[] = {
+ BinaryenConst(module, BinaryenLiteralInt32(0))
+ };
+ BinaryenExpressionRef list[] = {
+ BinaryenCall(module, "print", args, 1, BinaryenTypeNone()),
+ BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0,
+ BinaryenTypeInt32()))
+ };
+
+ b0 = RelooperAddBlockWithSwitch(relooper,
+ BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()),
+ BinaryenBinary(module,
+ BinaryenRemUInt32(),
+ BinaryenGetLocal(module, 0, BinaryenTypeInt32()),
+ BinaryenConst(module, BinaryenLiteralInt32(1))
+ )
+ );
+
+ }
+
+ RelooperBlockRef b1;
+ {
+ BinaryenExpressionRef args[] = {
+ BinaryenConst(module, BinaryenLiteralInt32(1))
+ };
+ BinaryenExpressionRef list[] = {
+ BinaryenCall(module, "print", args, 1, BinaryenTypeNone()),
+ BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0,
+ BinaryenTypeInt32()))
+ };
+
+ b1 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()));
+
+ }
+
+ RelooperBlockRef b2;
+ {
+ BinaryenExpressionRef args[] = {
+ BinaryenConst(module, BinaryenLiteralInt32(1))
+ };
+ BinaryenExpressionRef list[] = {
+ BinaryenCall(module, "print", args, 1, BinaryenTypeNone()),
+ BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0,
+ BinaryenTypeInt32()))
+ };
+
+ b2 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()));
+
+ }
+
+ RelooperBlockRef b3;
+ {
+ BinaryenExpressionRef args[] = {
+ BinaryenConst(module, BinaryenLiteralInt32(1))
+ };
+ BinaryenExpressionRef list[] = {
+ BinaryenCall(module, "print", args, 1, BinaryenTypeNone()),
+ BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0,
+ BinaryenTypeInt32()))
+ };
+
+ b3 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()));
+ }
+
+ RelooperBlockRef b4;
+ {
+ BinaryenExpressionRef args[] = {
+ BinaryenConst(module, BinaryenLiteralInt32(1))
+ };
+ BinaryenExpressionRef list[] = {
+ BinaryenCall(module, "print", args, 1, BinaryenTypeNone()),
+ BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0,
+ BinaryenTypeInt32()))
+ };
+
+ b4 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()));
+ }
+
+ // Separate branch for each.
+ // In this testcase, target blocks have identical contents (print 1),
+ // and branches have identical phis.
+ {
+ BinaryenIndex indexes[] = { 1, 4, 9 };
+ RelooperAddBranchForSwitch(b0, b1, indexes, 3,
+ BinaryenDrop(module,
+ BinaryenConst(module, BinaryenLiteralInt32(4))
+ )
+ );
+ }
+ {
+ BinaryenIndex indexes[] = { 3, 6 };
+ RelooperAddBranchForSwitch(b0, b2, indexes, 2,
+ BinaryenDrop(module,
+ BinaryenConst(module, BinaryenLiteralInt32(4))
+ )
+ );
+ }
+ {
+ BinaryenIndex indexes[] = { 5, 25, 125 };
+ RelooperAddBranchForSwitch(b0, b3, indexes, 3,
+ BinaryenDrop(module,
+ BinaryenConst(module, BinaryenLiteralInt32(4))
+ )
+ );
+ }
+ RelooperAddBranchForSwitch(b0, b4, NULL, 0, NULL);
+
+ BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, b0, 1);
+
+ BinaryenFunctionTypeRef v = BinaryenAddFunctionType(module, "v",
+ BinaryenTypeNone(),
+ NULL, 0);
+ // locals: state, free-for-label
+ BinaryenType localTypes[] = { BinaryenTypeInt32(), BinaryenTypeInt32() };
+ BinaryenFunctionRef theMain = BinaryenAddFunction(module, "main", v,
+ localTypes, 2, body);
+ BinaryenSetStart(module, theMain);
+
+ // import
+
+ BinaryenType iparams[] = { BinaryenTypeInt32() };
+ BinaryenFunctionTypeRef vi = BinaryenAddFunctionType(module, "vi",
+ BinaryenTypeNone(),
+ iparams, 1);
+ BinaryenAddFunctionImport(module, "print", "spectest", "print", vi);
+
+ // memory
+ BinaryenSetMemory(module, 1, 1, "mem", NULL, NULL, NULL, 0, 0);
+
+ // optionally, optimize
+ if (0) BinaryenModuleOptimize(module);
+
+ assert(BinaryenModuleValidate(module));
+
+ // write it out
+
+ BinaryenModulePrint(module);
+
+ BinaryenModuleDispose(module);
+
+ return 0;
+}
diff --git a/test/example/relooper-merge2.txt b/test/example/relooper-merge2.txt
new file mode 100644
index 000000000..fa356d1a0
--- /dev/null
+++ b/test/example/relooper-merge2.txt
@@ -0,0 +1,133 @@
+(module
+ (type $i (func (result i32)))
+ (type $v (func))
+ (type $vi (func (param i32)))
+ (import "spectest" "print" (func $print (param i32)))
+ (memory $0 1 1)
+ (export "mem" (memory $0))
+ (start $main)
+ (func $check (; 1 ;) (type $i) (result i32)
+ (if
+ (i32.ge_u
+ (i32.load
+ (i32.const 4)
+ )
+ (i32.const 48)
+ )
+ (unreachable)
+ )
+ (i32.store
+ (i32.const 4)
+ (i32.add
+ (i32.load
+ (i32.const 4)
+ )
+ (i32.const 4)
+ )
+ )
+ (call $print
+ (i32.sub
+ (i32.const 0)
+ (i32.load offset=4
+ (i32.load
+ (i32.const 4)
+ )
+ )
+ )
+ )
+ (i32.load offset=4
+ (i32.load
+ (i32.const 4)
+ )
+ )
+ )
+ (func $main (; 2 ;) (type $v)
+ (local $0 i32)
+ (local $1 i32)
+ (block
+ (call $print
+ (i32.const 0)
+ )
+ (set_local $0
+ (call $check)
+ )
+ )
+ (block $switch$1$leave
+ (block $switch$1$default
+ (block $switch$1$case$4
+ (block $switch$1$case$3
+ (block $switch$1$case$2
+ (br_table $switch$1$default $switch$1$case$2 $switch$1$default $switch$1$case$3 $switch$1$case$2 $switch$1$case$4 $switch$1$case$3 $switch$1$default $switch$1$default $switch$1$case$2 $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$case$4 $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$default $switch$1$case$4 $switch$1$default
+ (i32.rem_u
+ (get_local $0)
+ (i32.const 1)
+ )
+ )
+ )
+ (block
+ (drop
+ (i32.const 4)
+ )
+ (block
+ (block
+ (call $print
+ (i32.const 1)
+ )
+ (set_local $0
+ (call $check)
+ )
+ )
+ )
+ )
+ (br $switch$1$leave)
+ )
+ (block
+ (drop
+ (i32.const 4)
+ )
+ (block
+ (block
+ (call $print
+ (i32.const 1)
+ )
+ (set_local $0
+ (call $check)
+ )
+ )
+ )
+ )
+ (br $switch$1$leave)
+ )
+ (block
+ (drop
+ (i32.const 4)
+ )
+ (block
+ (block
+ (call $print
+ (i32.const 1)
+ )
+ (set_local $0
+ (call $check)
+ )
+ )
+ )
+ )
+ (br $switch$1$leave)
+ )
+ (block
+ (block
+ (block
+ (call $print
+ (i32.const 1)
+ )
+ (set_local $0
+ (call $check)
+ )
+ )
+ )
+ )
+ (br $switch$1$leave)
+ )
+ )
+)
diff --git a/test/example/relooper-merge3.c b/test/example/relooper-merge3.c
new file mode 100644
index 000000000..09cb98138
--- /dev/null
+++ b/test/example/relooper-merge3.c
@@ -0,0 +1,210 @@
+
+
+#include <assert.h>
+#include <stdio.h>
+
+#include "binaryen-c.h"
+
+// globals: address 4 is index
+// decisions are at address 8+
+
+int main() {
+ BinaryenModuleRef module = BinaryenModuleCreate();
+
+ // check()
+
+ // if the end, halt
+ BinaryenExpressionRef halter = BinaryenIf(module,
+ BinaryenBinary(module,
+ BinaryenGeUInt32(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(4))),
+ BinaryenConst(module, BinaryenLiteralInt32(4 * 12)) // jumps of 4 bytes
+ ),
+ BinaryenUnreachable(module),
+ NULL
+ );
+ // increment index
+ BinaryenExpressionRef incer = BinaryenStore(module,
+ 4, 0, 0,
+ BinaryenConst(module, BinaryenLiteralInt32(4)),
+ BinaryenBinary(module,
+ BinaryenAddInt32(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(4))),
+ BinaryenConst(module, BinaryenLiteralInt32(4))
+ ),
+ BinaryenTypeInt32()
+ );
+
+ // optionally, print the return value
+ BinaryenExpressionRef args[] = {
+ BinaryenBinary(module,
+ BinaryenSubInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(0)),
+ BinaryenLoad(module,
+ 4, 0, 4, 0, BinaryenTypeInt32(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(4)))
+ )
+ )
+ };
+ BinaryenExpressionRef debugger;
+ if (1) debugger = BinaryenCall(module, "print", args, 1,
+ BinaryenTypeNone());
+ else debugger = BinaryenNop(module);
+
+ // return the decision. need to subtract 4 that we just added,
+ // and add 8 since that's where we start, so overall offset 4
+ BinaryenExpressionRef returner = BinaryenLoad(module,
+ 4, 0, 4, 0, BinaryenTypeInt32(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(4)))
+ );
+ BinaryenExpressionRef checkBodyList[] = { halter, incer, debugger,
+ returner };
+ BinaryenExpressionRef checkBody = BinaryenBlock(module,
+ NULL, checkBodyList, sizeof(checkBodyList) / sizeof(BinaryenExpressionRef),
+ BinaryenTypeInt32()
+ );
+ BinaryenFunctionTypeRef i = BinaryenAddFunctionType(module, "i",
+ BinaryenTypeInt32(),
+ NULL, 0);
+ BinaryenAddFunction(module, "check", i, NULL, 0, checkBody);
+
+ // contents of main() begin here
+
+ RelooperRef relooper = RelooperCreate(module);
+
+
+ RelooperBlockRef b0;
+ {
+ BinaryenExpressionRef args[] = {
+ BinaryenConst(module, BinaryenLiteralInt32(0))
+ };
+ BinaryenExpressionRef list[] = {
+ BinaryenCall(module, "print", args, 1, BinaryenTypeNone()),
+ BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0,
+ BinaryenTypeInt32()))
+ };
+
+ b0 = RelooperAddBlockWithSwitch(relooper,
+ BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()),
+ BinaryenBinary(module,
+ BinaryenRemUInt32(),
+ BinaryenGetLocal(module, 0, BinaryenTypeInt32()),
+ BinaryenConst(module, BinaryenLiteralInt32(1))
+ )
+ );
+
+ }
+
+ RelooperBlockRef b1;
+ {
+ BinaryenExpressionRef args[] = {
+ BinaryenConst(module, BinaryenLiteralInt32(1))
+ };
+ BinaryenExpressionRef list[] = {
+ BinaryenCall(module, "print", args, 1, BinaryenTypeNone()),
+ BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0,
+ BinaryenTypeInt32()))
+ };
+
+ b1 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()));
+
+ }
+
+ RelooperBlockRef b2;
+ {
+ BinaryenExpressionRef args[] = {
+ BinaryenConst(module, BinaryenLiteralInt32(1))
+ };
+ BinaryenExpressionRef list[] = {
+ BinaryenCall(module, "print", args, 1, BinaryenTypeNone()),
+ BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0,
+ BinaryenTypeInt32()))
+ };
+
+ b2 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()));
+
+ }
+
+ RelooperBlockRef b3;
+ {
+ BinaryenExpressionRef args[] = {
+ BinaryenConst(module, BinaryenLiteralInt32(2))
+ };
+ BinaryenExpressionRef list[] = {
+ BinaryenCall(module, "print", args, 1, BinaryenTypeNone()),
+ BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0,
+ BinaryenTypeInt32()))
+ };
+
+ b3 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()));
+ }
+
+ RelooperBlockRef b4;
+ {
+ BinaryenExpressionRef args[] = {
+ BinaryenConst(module, BinaryenLiteralInt32(3))
+ };
+ BinaryenExpressionRef list[] = {
+ BinaryenCall(module, "print", args, 1, BinaryenTypeNone()),
+ BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0,
+ BinaryenTypeInt32()))
+ };
+
+ b4 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()));
+ }
+
+ // Separate branch for each.
+ // In this testcase, two blocks out of 4 can be merged.
+ {
+ BinaryenIndex indexes[] = { 1, 4, 9 };
+ RelooperAddBranchForSwitch(b0, b1, indexes, 3, NULL);
+ }
+ {
+ BinaryenIndex indexes[] = { 3, 6 };
+ RelooperAddBranchForSwitch(b0, b2, indexes, 2, NULL);
+ }
+ {
+ BinaryenIndex indexes[] = { 5 };
+ RelooperAddBranchForSwitch(b0, b3, indexes, 1, NULL);
+ }
+ RelooperAddBranchForSwitch(b0, b4, NULL, 0, NULL);
+
+ BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, b0, 1);
+
+ BinaryenFunctionTypeRef v = BinaryenAddFunctionType(module, "v",
+ BinaryenTypeNone(),
+ NULL, 0);
+ // locals: state, free-for-label
+ BinaryenType localTypes[] = { BinaryenTypeInt32(), BinaryenTypeInt32() };
+ BinaryenFunctionRef theMain = BinaryenAddFunction(module, "main", v,
+ localTypes, 2, body);
+ BinaryenSetStart(module, theMain);
+
+ // import
+
+ BinaryenType iparams[] = { BinaryenTypeInt32() };
+ BinaryenFunctionTypeRef vi = BinaryenAddFunctionType(module, "vi",
+ BinaryenTypeNone(),
+ iparams, 1);
+ BinaryenAddFunctionImport(module, "print", "spectest", "print", vi);
+
+ // memory
+ BinaryenSetMemory(module, 1, 1, "mem", NULL, NULL, NULL, 0, 0);
+
+ // optionally, optimize
+ if (0) BinaryenModuleOptimize(module);
+
+ assert(BinaryenModuleValidate(module));
+
+ // write it out
+
+ BinaryenModulePrint(module);
+
+ BinaryenModuleDispose(module);
+
+ return 0;
+}
diff --git a/test/example/relooper-merge3.txt b/test/example/relooper-merge3.txt
new file mode 100644
index 000000000..b19f8c599
--- /dev/null
+++ b/test/example/relooper-merge3.txt
@@ -0,0 +1,109 @@
+(module
+ (type $i (func (result i32)))
+ (type $v (func))
+ (type $vi (func (param i32)))
+ (import "spectest" "print" (func $print (param i32)))
+ (memory $0 1 1)
+ (export "mem" (memory $0))
+ (start $main)
+ (func $check (; 1 ;) (type $i) (result i32)
+ (if
+ (i32.ge_u
+ (i32.load
+ (i32.const 4)
+ )
+ (i32.const 48)
+ )
+ (unreachable)
+ )
+ (i32.store
+ (i32.const 4)
+ (i32.add
+ (i32.load
+ (i32.const 4)
+ )
+ (i32.const 4)
+ )
+ )
+ (call $print
+ (i32.sub
+ (i32.const 0)
+ (i32.load offset=4
+ (i32.load
+ (i32.const 4)
+ )
+ )
+ )
+ )
+ (i32.load offset=4
+ (i32.load
+ (i32.const 4)
+ )
+ )
+ )
+ (func $main (; 2 ;) (type $v)
+ (local $0 i32)
+ (local $1 i32)
+ (block
+ (call $print
+ (i32.const 0)
+ )
+ (set_local $0
+ (call $check)
+ )
+ )
+ (block $switch$1$leave
+ (block $switch$1$default
+ (block $switch$1$case$4
+ (block $switch$1$case$2
+ (br_table $switch$1$default $switch$1$case$2 $switch$1$default $switch$1$case$2 $switch$1$case$2 $switch$1$case$4 $switch$1$case$2 $switch$1$default $switch$1$default $switch$1$case$2 $switch$1$default
+ (i32.rem_u
+ (get_local $0)
+ (i32.const 1)
+ )
+ )
+ )
+ (block
+ (block
+ (block
+ (call $print
+ (i32.const 1)
+ )
+ (set_local $0
+ (call $check)
+ )
+ )
+ )
+ )
+ (br $switch$1$leave)
+ )
+ (block
+ (block
+ (block
+ (call $print
+ (i32.const 2)
+ )
+ (set_local $0
+ (call $check)
+ )
+ )
+ )
+ )
+ (br $switch$1$leave)
+ )
+ (block
+ (block
+ (block
+ (call $print
+ (i32.const 3)
+ )
+ (set_local $0
+ (call $check)
+ )
+ )
+ )
+ )
+ (br $switch$1$leave)
+ )
+ )
+)
diff --git a/test/example/relooper-merge4.c b/test/example/relooper-merge4.c
new file mode 100644
index 000000000..41e094315
--- /dev/null
+++ b/test/example/relooper-merge4.c
@@ -0,0 +1,210 @@
+
+
+#include <assert.h>
+#include <stdio.h>
+
+#include "binaryen-c.h"
+
+// globals: address 4 is index
+// decisions are at address 8+
+
+int main() {
+ BinaryenModuleRef module = BinaryenModuleCreate();
+
+ // check()
+
+ // if the end, halt
+ BinaryenExpressionRef halter = BinaryenIf(module,
+ BinaryenBinary(module,
+ BinaryenGeUInt32(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(4))),
+ BinaryenConst(module, BinaryenLiteralInt32(4 * 12)) // jumps of 4 bytes
+ ),
+ BinaryenUnreachable(module),
+ NULL
+ );
+ // increment index
+ BinaryenExpressionRef incer = BinaryenStore(module,
+ 4, 0, 0,
+ BinaryenConst(module, BinaryenLiteralInt32(4)),
+ BinaryenBinary(module,
+ BinaryenAddInt32(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(4))),
+ BinaryenConst(module, BinaryenLiteralInt32(4))
+ ),
+ BinaryenTypeInt32()
+ );
+
+ // optionally, print the return value
+ BinaryenExpressionRef args[] = {
+ BinaryenBinary(module,
+ BinaryenSubInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(0)),
+ BinaryenLoad(module,
+ 4, 0, 4, 0, BinaryenTypeInt32(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(4)))
+ )
+ )
+ };
+ BinaryenExpressionRef debugger;
+ if (1) debugger = BinaryenCall(module, "print", args, 1,
+ BinaryenTypeNone());
+ else debugger = BinaryenNop(module);
+
+ // return the decision. need to subtract 4 that we just added,
+ // and add 8 since that's where we start, so overall offset 4
+ BinaryenExpressionRef returner = BinaryenLoad(module,
+ 4, 0, 4, 0, BinaryenTypeInt32(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(4)))
+ );
+ BinaryenExpressionRef checkBodyList[] = { halter, incer, debugger,
+ returner };
+ BinaryenExpressionRef checkBody = BinaryenBlock(module,
+ NULL, checkBodyList, sizeof(checkBodyList) / sizeof(BinaryenExpressionRef),
+ BinaryenTypeInt32()
+ );
+ BinaryenFunctionTypeRef i = BinaryenAddFunctionType(module, "i",
+ BinaryenTypeInt32(),
+ NULL, 0);
+ BinaryenAddFunction(module, "check", i, NULL, 0, checkBody);
+
+ // contents of main() begin here
+
+ RelooperRef relooper = RelooperCreate(module);
+
+
+ RelooperBlockRef b0;
+ {
+ BinaryenExpressionRef args[] = {
+ BinaryenConst(module, BinaryenLiteralInt32(0))
+ };
+ BinaryenExpressionRef list[] = {
+ BinaryenCall(module, "print", args, 1, BinaryenTypeNone()),
+ BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0,
+ BinaryenTypeInt32()))
+ };
+
+ b0 = RelooperAddBlockWithSwitch(relooper,
+ BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()),
+ BinaryenBinary(module,
+ BinaryenRemUInt32(),
+ BinaryenGetLocal(module, 0, BinaryenTypeInt32()),
+ BinaryenConst(module, BinaryenLiteralInt32(1))
+ )
+ );
+
+ }
+
+ RelooperBlockRef b1;
+ {
+ BinaryenExpressionRef args[] = {
+ BinaryenConst(module, BinaryenLiteralInt32(1))
+ };
+ BinaryenExpressionRef list[] = {
+ BinaryenCall(module, "print", args, 1, BinaryenTypeNone()),
+ BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0,
+ BinaryenTypeInt32()))
+ };
+
+ b1 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()));
+
+ }
+
+ RelooperBlockRef b2;
+ {
+ BinaryenExpressionRef args[] = {
+ BinaryenConst(module, BinaryenLiteralInt32(1))
+ };
+ BinaryenExpressionRef list[] = {
+ BinaryenCall(module, "print", args, 1, BinaryenTypeNone()),
+ BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0,
+ BinaryenTypeInt32()))
+ };
+
+ b2 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()));
+
+ }
+
+ RelooperBlockRef b3;
+ {
+ BinaryenExpressionRef args[] = {
+ BinaryenConst(module, BinaryenLiteralInt32(2))
+ };
+ BinaryenExpressionRef list[] = {
+ BinaryenCall(module, "print", args, 1, BinaryenTypeNone()),
+ BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0,
+ BinaryenTypeInt32()))
+ };
+
+ b3 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()));
+ }
+
+ RelooperBlockRef b4;
+ {
+ BinaryenExpressionRef args[] = {
+ BinaryenConst(module, BinaryenLiteralInt32(3))
+ };
+ BinaryenExpressionRef list[] = {
+ BinaryenCall(module, "print", args, 1, BinaryenTypeNone()),
+ BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0,
+ BinaryenTypeInt32()))
+ };
+
+ b4 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()));
+ }
+
+ // Separate branch for each.
+ // In this testcase, two blocks out of 4 can be merged.
+ {
+ BinaryenIndex indexes[] = { 1, 4, 9 };
+ RelooperAddBranchForSwitch(b0, b4, indexes, 3, NULL);
+ }
+ {
+ BinaryenIndex indexes[] = { 3, 6 };
+ RelooperAddBranchForSwitch(b0, b2, indexes, 2, NULL);
+ }
+ {
+ BinaryenIndex indexes[] = { 5 };
+ RelooperAddBranchForSwitch(b0, b3, indexes, 1, NULL);
+ }
+ RelooperAddBranchForSwitch(b0, b1, NULL, 0, NULL);
+
+ BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, b0, 1);
+
+ BinaryenFunctionTypeRef v = BinaryenAddFunctionType(module, "v",
+ BinaryenTypeNone(),
+ NULL, 0);
+ // locals: state, free-for-label
+ BinaryenType localTypes[] = { BinaryenTypeInt32(), BinaryenTypeInt32() };
+ BinaryenFunctionRef theMain = BinaryenAddFunction(module, "main", v,
+ localTypes, 2, body);
+ BinaryenSetStart(module, theMain);
+
+ // import
+
+ BinaryenType iparams[] = { BinaryenTypeInt32() };
+ BinaryenFunctionTypeRef vi = BinaryenAddFunctionType(module, "vi",
+ BinaryenTypeNone(),
+ iparams, 1);
+ BinaryenAddFunctionImport(module, "print", "spectest", "print", vi);
+
+ // memory
+ BinaryenSetMemory(module, 1, 1, "mem", NULL, NULL, NULL, 0, 0);
+
+ // optionally, optimize
+ if (0) BinaryenModuleOptimize(module);
+
+ assert(BinaryenModuleValidate(module));
+
+ // write it out
+
+ BinaryenModulePrint(module);
+
+ BinaryenModuleDispose(module);
+
+ return 0;
+}
diff --git a/test/example/relooper-merge4.txt b/test/example/relooper-merge4.txt
new file mode 100644
index 000000000..c2162a988
--- /dev/null
+++ b/test/example/relooper-merge4.txt
@@ -0,0 +1,109 @@
+(module
+ (type $i (func (result i32)))
+ (type $v (func))
+ (type $vi (func (param i32)))
+ (import "spectest" "print" (func $print (param i32)))
+ (memory $0 1 1)
+ (export "mem" (memory $0))
+ (start $main)
+ (func $check (; 1 ;) (type $i) (result i32)
+ (if
+ (i32.ge_u
+ (i32.load
+ (i32.const 4)
+ )
+ (i32.const 48)
+ )
+ (unreachable)
+ )
+ (i32.store
+ (i32.const 4)
+ (i32.add
+ (i32.load
+ (i32.const 4)
+ )
+ (i32.const 4)
+ )
+ )
+ (call $print
+ (i32.sub
+ (i32.const 0)
+ (i32.load offset=4
+ (i32.load
+ (i32.const 4)
+ )
+ )
+ )
+ )
+ (i32.load offset=4
+ (i32.load
+ (i32.const 4)
+ )
+ )
+ )
+ (func $main (; 2 ;) (type $v)
+ (local $0 i32)
+ (local $1 i32)
+ (block
+ (call $print
+ (i32.const 0)
+ )
+ (set_local $0
+ (call $check)
+ )
+ )
+ (block $switch$1$leave
+ (block $switch$1$case$4
+ (block $switch$1$default
+ (block $switch$1$case$5
+ (br_table $switch$1$default $switch$1$case$5 $switch$1$default $switch$1$default $switch$1$case$5 $switch$1$case$4 $switch$1$default $switch$1$default $switch$1$default $switch$1$case$5 $switch$1$default
+ (i32.rem_u
+ (get_local $0)
+ (i32.const 1)
+ )
+ )
+ )
+ (block
+ (block
+ (block
+ (call $print
+ (i32.const 3)
+ )
+ (set_local $0
+ (call $check)
+ )
+ )
+ )
+ )
+ (br $switch$1$leave)
+ )
+ (block
+ (block
+ (block
+ (call $print
+ (i32.const 1)
+ )
+ (set_local $0
+ (call $check)
+ )
+ )
+ )
+ )
+ (br $switch$1$leave)
+ )
+ (block
+ (block
+ (block
+ (call $print
+ (i32.const 2)
+ )
+ (set_local $0
+ (call $check)
+ )
+ )
+ )
+ )
+ (br $switch$1$leave)
+ )
+ )
+)
diff --git a/test/example/relooper-merge5.c b/test/example/relooper-merge5.c
new file mode 100644
index 000000000..153ce963a
--- /dev/null
+++ b/test/example/relooper-merge5.c
@@ -0,0 +1,210 @@
+
+
+#include <assert.h>
+#include <stdio.h>
+
+#include "binaryen-c.h"
+
+// globals: address 4 is index
+// decisions are at address 8+
+
+int main() {
+ BinaryenModuleRef module = BinaryenModuleCreate();
+
+ // check()
+
+ // if the end, halt
+ BinaryenExpressionRef halter = BinaryenIf(module,
+ BinaryenBinary(module,
+ BinaryenGeUInt32(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(4))),
+ BinaryenConst(module, BinaryenLiteralInt32(4 * 12)) // jumps of 4 bytes
+ ),
+ BinaryenUnreachable(module),
+ NULL
+ );
+ // increment index
+ BinaryenExpressionRef incer = BinaryenStore(module,
+ 4, 0, 0,
+ BinaryenConst(module, BinaryenLiteralInt32(4)),
+ BinaryenBinary(module,
+ BinaryenAddInt32(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(4))),
+ BinaryenConst(module, BinaryenLiteralInt32(4))
+ ),
+ BinaryenTypeInt32()
+ );
+
+ // optionally, print the return value
+ BinaryenExpressionRef args[] = {
+ BinaryenBinary(module,
+ BinaryenSubInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(0)),
+ BinaryenLoad(module,
+ 4, 0, 4, 0, BinaryenTypeInt32(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(4)))
+ )
+ )
+ };
+ BinaryenExpressionRef debugger;
+ if (1) debugger = BinaryenCall(module, "print", args, 1,
+ BinaryenTypeNone());
+ else debugger = BinaryenNop(module);
+
+ // return the decision. need to subtract 4 that we just added,
+ // and add 8 since that's where we start, so overall offset 4
+ BinaryenExpressionRef returner = BinaryenLoad(module,
+ 4, 0, 4, 0, BinaryenTypeInt32(),
+ BinaryenLoad(module, 4, 0, 0, 0, BinaryenTypeInt32(),
+ BinaryenConst(module, BinaryenLiteralInt32(4)))
+ );
+ BinaryenExpressionRef checkBodyList[] = { halter, incer, debugger,
+ returner };
+ BinaryenExpressionRef checkBody = BinaryenBlock(module,
+ NULL, checkBodyList, sizeof(checkBodyList) / sizeof(BinaryenExpressionRef),
+ BinaryenTypeInt32()
+ );
+ BinaryenFunctionTypeRef i = BinaryenAddFunctionType(module, "i",
+ BinaryenTypeInt32(),
+ NULL, 0);
+ BinaryenAddFunction(module, "check", i, NULL, 0, checkBody);
+
+ // contents of main() begin here
+
+ RelooperRef relooper = RelooperCreate(module);
+
+
+ RelooperBlockRef b0;
+ {
+ BinaryenExpressionRef args[] = {
+ BinaryenConst(module, BinaryenLiteralInt32(0))
+ };
+ BinaryenExpressionRef list[] = {
+ BinaryenCall(module, "print", args, 1, BinaryenTypeNone()),
+ BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0,
+ BinaryenTypeInt32()))
+ };
+
+ b0 = RelooperAddBlockWithSwitch(relooper,
+ BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()),
+ BinaryenBinary(module,
+ BinaryenRemUInt32(),
+ BinaryenGetLocal(module, 0, BinaryenTypeInt32()),
+ BinaryenConst(module, BinaryenLiteralInt32(1))
+ )
+ );
+
+ }
+
+ RelooperBlockRef b1;
+ {
+ BinaryenExpressionRef args[] = {
+ BinaryenConst(module, BinaryenLiteralInt32(1))
+ };
+ BinaryenExpressionRef list[] = {
+ BinaryenCall(module, "print", args, 1, BinaryenTypeNone()),
+ BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0,
+ BinaryenTypeInt32()))
+ };
+
+ b1 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()));
+
+ }
+
+ RelooperBlockRef b2;
+ {
+ BinaryenExpressionRef args[] = {
+ BinaryenConst(module, BinaryenLiteralInt32(1))
+ };
+ BinaryenExpressionRef list[] = {
+ BinaryenCall(module, "print", args, 1, BinaryenTypeNone()),
+ BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0,
+ BinaryenTypeInt32()))
+ };
+
+ b2 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()));
+
+ }
+
+ RelooperBlockRef b3;
+ {
+ BinaryenExpressionRef args[] = {
+ BinaryenConst(module, BinaryenLiteralInt32(2))
+ };
+ BinaryenExpressionRef list[] = {
+ BinaryenCall(module, "print", args, 1, BinaryenTypeNone()),
+ BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0,
+ BinaryenTypeInt32()))
+ };
+
+ b3 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()));
+ }
+
+ RelooperBlockRef b4;
+ {
+ BinaryenExpressionRef args[] = {
+ BinaryenConst(module, BinaryenLiteralInt32(3))
+ };
+ BinaryenExpressionRef list[] = {
+ BinaryenCall(module, "print", args, 1, BinaryenTypeNone()),
+ BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0,
+ BinaryenTypeInt32()))
+ };
+
+ b4 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenTypeNone()));
+ }
+
+ // Separate branch for each.
+ // In this testcase, two blocks out of 4 can be merged.
+ RelooperAddBranchForSwitch(b0, b1, NULL, 0, NULL);
+ {
+ BinaryenIndex indexes[] = { 1, 4, 9 };
+ RelooperAddBranchForSwitch(b0, b4, indexes, 3, NULL);
+ }
+ {
+ BinaryenIndex indexes[] = { 3, 6 };
+ RelooperAddBranchForSwitch(b0, b2, indexes, 2, NULL);
+ }
+ {
+ BinaryenIndex indexes[] = { 5 };
+ RelooperAddBranchForSwitch(b0, b3, indexes, 1, NULL);
+ }
+
+ BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, b0, 1);
+
+ BinaryenFunctionTypeRef v = BinaryenAddFunctionType(module, "v",
+ BinaryenTypeNone(),
+ NULL, 0);
+ // locals: state, free-for-label
+ BinaryenType localTypes[] = { BinaryenTypeInt32(), BinaryenTypeInt32() };
+ BinaryenFunctionRef theMain = BinaryenAddFunction(module, "main", v,
+ localTypes, 2, body);
+ BinaryenSetStart(module, theMain);
+
+ // import
+
+ BinaryenType iparams[] = { BinaryenTypeInt32() };
+ BinaryenFunctionTypeRef vi = BinaryenAddFunctionType(module, "vi",
+ BinaryenTypeNone(),
+ iparams, 1);
+ BinaryenAddFunctionImport(module, "print", "spectest", "print", vi);
+
+ // memory
+ BinaryenSetMemory(module, 1, 1, "mem", NULL, NULL, NULL, 0, 0);
+
+ // optionally, optimize
+ if (0) BinaryenModuleOptimize(module);
+
+ assert(BinaryenModuleValidate(module));
+
+ // write it out
+
+ BinaryenModulePrint(module);
+
+ BinaryenModuleDispose(module);
+
+ return 0;
+}
diff --git a/test/example/relooper-merge5.txt b/test/example/relooper-merge5.txt
new file mode 100644
index 000000000..5b0db4535
--- /dev/null
+++ b/test/example/relooper-merge5.txt
@@ -0,0 +1,109 @@
+(module
+ (type $i (func (result i32)))
+ (type $v (func))
+ (type $vi (func (param i32)))
+ (import "spectest" "print" (func $print (param i32)))
+ (memory $0 1 1)
+ (export "mem" (memory $0))
+ (start $main)
+ (func $check (; 1 ;) (type $i) (result i32)
+ (if
+ (i32.ge_u
+ (i32.load
+ (i32.const 4)
+ )
+ (i32.const 48)
+ )
+ (unreachable)
+ )
+ (i32.store
+ (i32.const 4)
+ (i32.add
+ (i32.load
+ (i32.const 4)
+ )
+ (i32.const 4)
+ )
+ )
+ (call $print
+ (i32.sub
+ (i32.const 0)
+ (i32.load offset=4
+ (i32.load
+ (i32.const 4)
+ )
+ )
+ )
+ )
+ (i32.load offset=4
+ (i32.load
+ (i32.const 4)
+ )
+ )
+ )
+ (func $main (; 2 ;) (type $v)
+ (local $0 i32)
+ (local $1 i32)
+ (block
+ (call $print
+ (i32.const 0)
+ )
+ (set_local $0
+ (call $check)
+ )
+ )
+ (block $switch$1$leave
+ (block $switch$1$case$4
+ (block $switch$1$case$5
+ (block $switch$1$default
+ (br_table $switch$1$default $switch$1$case$5 $switch$1$default $switch$1$default $switch$1$case$5 $switch$1$case$4 $switch$1$default $switch$1$default $switch$1$default $switch$1$case$5 $switch$1$default
+ (i32.rem_u
+ (get_local $0)
+ (i32.const 1)
+ )
+ )
+ )
+ (block
+ (block
+ (block
+ (call $print
+ (i32.const 1)
+ )
+ (set_local $0
+ (call $check)
+ )
+ )
+ )
+ )
+ (br $switch$1$leave)
+ )
+ (block
+ (block
+ (block
+ (call $print
+ (i32.const 3)
+ )
+ (set_local $0
+ (call $check)
+ )
+ )
+ )
+ )
+ (br $switch$1$leave)
+ )
+ (block
+ (block
+ (block
+ (call $print
+ (i32.const 2)
+ )
+ (set_local $0
+ (call $check)
+ )
+ )
+ )
+ )
+ (br $switch$1$leave)
+ )
+ )
+)