diff options
Diffstat (limited to 'test')
26 files changed, 3066 insertions, 558 deletions
diff --git a/test/binaryen.js/kitchen-sink.js b/test/binaryen.js/kitchen-sink.js index 33c98d97a..b642d3542 100644 --- a/test/binaryen.js/kitchen-sink.js +++ b/test/binaryen.js/kitchen-sink.js @@ -295,13 +295,13 @@ function test_relooper() { } { // trivial: just one block - var relooper = new Binaryen.Relooper(); + var relooper = new Binaryen.Relooper(module); var block = relooper.addBlock(makeCallCheck(1337)); var body = relooper.renderAndDispose(block, 0, module); module.addFunction("just-one-block", v, localTypes, body); } { // two blocks - var relooper = new Binaryen.Relooper(); + var relooper = new Binaryen.Relooper(module); var block0 = relooper.addBlock(makeCallCheck(0)); var block1 = relooper.addBlock(makeCallCheck(1)); relooper.addBranch(block0, block1); // no condition, no code on branch @@ -309,7 +309,7 @@ function test_relooper() { module.addFunction("two-blocks", v, localTypes, body); } { // two blocks with code between them - var relooper = new Binaryen.Relooper(); + var relooper = new Binaryen.Relooper(module); var block0 = relooper.addBlock(makeCallCheck(0)); var block1 = relooper.addBlock(makeCallCheck(1)); relooper.addBranch(block0, block1, null, makeDroppedInt32(77)); // code on branch @@ -317,7 +317,7 @@ function test_relooper() { module.addFunction("two-blocks-plus-code", v, localTypes, body); } { // two blocks in a loop - var relooper = new Binaryen.Relooper(); + var relooper = new Binaryen.Relooper(module); var block0 = relooper.addBlock(makeCallCheck(0)); var block1 = relooper.addBlock(makeCallCheck(1)); relooper.addBranch(block0, block1, null, null); @@ -326,7 +326,7 @@ function test_relooper() { module.addFunction("loop", v, localTypes, body); } { // two blocks in a loop with codes - var relooper = new Binaryen.Relooper(); + var relooper = new Binaryen.Relooper(module); var block0 = relooper.addBlock(makeCallCheck(0)); var block1 = relooper.addBlock(makeCallCheck(1)); relooper.addBranch(block0, block1, null, makeDroppedInt32(33)); @@ -335,7 +335,7 @@ function test_relooper() { module.addFunction("loop-plus-code", v, localTypes, body); } { // split - var relooper = new Binaryen.Relooper(); + var relooper = new Binaryen.Relooper(module); var block0 = relooper.addBlock(makeCallCheck(0)); var block1 = relooper.addBlock(makeCallCheck(1)); var block2 = relooper.addBlock(makeCallCheck(2)); @@ -345,7 +345,7 @@ function test_relooper() { module.addFunction("split", v, localTypes, body); } { // split + code - var relooper = new Binaryen.Relooper(); + var relooper = new Binaryen.Relooper(module); var block0 = relooper.addBlock(makeCallCheck(0)); var block1 = relooper.addBlock(makeCallCheck(1)); var block2 = relooper.addBlock(makeCallCheck(2)); @@ -356,7 +356,7 @@ function test_relooper() { module.addFunction("split-plus-code", v, localTypes, body); } { // if - var relooper = new Binaryen.Relooper(); + var relooper = new Binaryen.Relooper(module); var block0 = relooper.addBlock(makeCallCheck(0)); var block1 = relooper.addBlock(makeCallCheck(1)); var block2 = relooper.addBlock(makeCallCheck(2)); @@ -367,7 +367,7 @@ function test_relooper() { module.addFunction("if", v, localTypes, body); } { // if + code - var relooper = new Binaryen.Relooper(); + var relooper = new Binaryen.Relooper(module); var block0 = relooper.addBlock(makeCallCheck(0)); var block1 = relooper.addBlock(makeCallCheck(1)); var block2 = relooper.addBlock(makeCallCheck(2)); @@ -379,7 +379,7 @@ function test_relooper() { module.addFunction("if-plus-code", v, localTypes, body); } { // if-else - var relooper = new Binaryen.Relooper(); + var relooper = new Binaryen.Relooper(module); var block0 = relooper.addBlock(makeCallCheck(0)); var block1 = relooper.addBlock(makeCallCheck(1)); var block2 = relooper.addBlock(makeCallCheck(2)); @@ -392,7 +392,7 @@ function test_relooper() { module.addFunction("if-else", v, localTypes, body); } { // loop+tail - var relooper = new Binaryen.Relooper(); + var relooper = new Binaryen.Relooper(module); var block0 = relooper.addBlock(makeCallCheck(0)); var block1 = relooper.addBlock(makeCallCheck(1)); var block2 = relooper.addBlock(makeCallCheck(2)); @@ -403,7 +403,7 @@ function test_relooper() { module.addFunction("loop-tail", v, localTypes, body); } { // nontrivial loop + phi to head - var relooper = new Binaryen.Relooper(); + var relooper = new Binaryen.Relooper(module); var block0 = relooper.addBlock(makeCallCheck(0)); var block1 = relooper.addBlock(makeCallCheck(1)); var block2 = relooper.addBlock(makeCallCheck(2)); @@ -424,7 +424,7 @@ function test_relooper() { module.addFunction("nontrivial-loop-plus-phi-to-head", v, localTypes, body); } { // switch - var relooper = new Binaryen.Relooper(); + var relooper = new Binaryen.Relooper(module); temp = makeInt32(-99); var block0 = relooper.addBlockWithSwitch(makeCallCheck(0), temp); var block1 = relooper.addBlock(makeCallCheck(1)); @@ -437,7 +437,7 @@ function test_relooper() { module.addFunction("switch", v, localTypes, body); } { // duff's device - var relooper = new Binaryen.Relooper(); + var relooper = new Binaryen.Relooper(module); var block0 = relooper.addBlock(makeCallCheck(0)); var block1 = relooper.addBlock(makeCallCheck(1)); var block2 = relooper.addBlock(makeCallCheck(2)); @@ -452,7 +452,7 @@ function test_relooper() { var i = module.addFunctionType("i", Binaryen.i32, []); { // return in a block - var relooper = new Binaryen.Relooper(); + var relooper = new Binaryen.Relooper(module); var list = module.block("the-list", [ makeCallCheck(42), module.return(makeInt32(1337)) ]); var block = relooper.addBlock(list); var body = relooper.renderAndDispose(block, 0, module); diff --git a/test/binaryen.js/kitchen-sink.js.txt b/test/binaryen.js/kitchen-sink.js.txt index 06894d137..2612f42b8 100644 --- a/test/binaryen.js/kitchen-sink.js.txt +++ b/test/binaryen.js/kitchen-sink.js.txt @@ -1048,7 +1048,7 @@ raw: ) (func $return (; 15 ;) (type $i) (result i32) (local $0 i32) - (block $the-list + (block (call $check (i32.const 42) ) @@ -2046,19 +2046,19 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5} 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] }; @@ -2072,12 +2072,12 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5} } 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] }; @@ -2093,12 +2093,12 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5} 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] }; @@ -2113,12 +2113,12 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5} 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] }; @@ -2137,12 +2137,12 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5} 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] }; @@ -2164,12 +2164,12 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5} 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] }; @@ -2195,12 +2195,12 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5} 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] }; @@ -2223,12 +2223,12 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5} 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] }; @@ -2257,12 +2257,12 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5} 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] }; @@ -2292,12 +2292,12 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5} 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] }; @@ -2320,12 +2320,12 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5} 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] }; @@ -2388,12 +2388,12 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5} 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)); { @@ -2433,12 +2433,12 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5} 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] }; @@ -2462,7 +2462,7 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5} 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]); @@ -2471,7 +2471,7 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5} 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] }; @@ -2484,7 +2484,7 @@ getExpressionInfo(f64.const)={"id":14,"type":4,"value":9.5} expressions[140] = BinaryenBlock(the_module, "the-list", children, 2, 0); } 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]); @@ -2966,7 +2966,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.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) + ) + ) +) diff --git a/test/passes/1.txt b/test/passes/1.txt index cf6a569eb..048ee292c 100644 --- a/test/passes/1.txt +++ b/test/passes/1.txt @@ -34,26 +34,21 @@ (func $loops (; 5 ;) (type $3) (param $0 i32) (if (get_local $0) - (loop $shape$3$continue + (loop $shape$2$continue (call $trivial) - (br $shape$3$continue) + (br $shape$2$continue) ) ) - (loop $shape$6$continue + (loop $shape$4$continue (call $trivial) - (br_if $shape$6$continue + (br_if $shape$4$continue (get_local $0) ) ) - (loop $shape$9$continue - (block $block$11$break - (call $trivial) - (br_if $block$11$break - (i32.eqz - (get_local $0) - ) - ) - (br $shape$9$continue) + (loop $shape$6$continue + (call $trivial) + (br_if $shape$6$continue + (get_local $0) ) ) ) @@ -187,10 +182,6 @@ ) ) (func $switch (; 10 ;) (type $3) (param $0 i32) - (if - (get_local $0) - (nop) - ) (block $block$6$break (call $switch (i32.const 1) @@ -221,9 +212,8 @@ (call $if-br-wat (i32.const 1) ) - (if + (br_if $block$2$break (get_local $0) - (br $block$2$break) ) ) (call $if-br-wat diff --git a/test/passes/flatten_rereloop.txt b/test/passes/flatten_rereloop.txt index efab836c8..c25505ec9 100644 --- a/test/passes/flatten_rereloop.txt +++ b/test/passes/flatten_rereloop.txt @@ -1,125 +1,407 @@ (module (type $0 (func (result f64))) + (type $1 (func (result i32))) + (type $2 (func)) + (type $3 (func (param i32))) + (type $4 (func (param i32) (result f32))) + (type $5 (func (result f32))) + (global $global (mut i32) (i32.const 0)) (func $0 (; 0 ;) (type $0) (result f64) (local $0 f64) (local $1 f64) (local $2 i32) - (block $block$2$break + (block + ) + (if + (i32.const 0) (block + (unreachable) ) - (if - (i32.const 0) - (br $block$2$break) + (block + (block + (set_local $0 + (f64.const -nan:0xfffffd63e4e5a) + ) + (set_local $1 + (get_local $0) + ) + (return + (get_local $1) + ) + ) + ) + ) + ) + (func $1 (; 1 ;) (type $1) (result i32) + (local $0 i32) + (local $1 i32) + (local $2 i32) + (block + (block $block$6$break (block + ) + (block $switch$1$leave + (block $switch$1$default + (block $switch$1$case$4 + (br_table $switch$1$case$4 $switch$1$case$4 $switch$1$default + (i32.const 0) + ) + ) + (block + (block + (unreachable) + ) + ) + ) (block - (nop) - (set_local $0 - (f64.const -nan:0xfffffd63e4e5a) + (br $block$6$break) + ) + ) + ) + (block + (block + ) + (block $switch$6$leave + (block $switch$6$default + (block $switch$6$case$3 + (br_table $switch$6$case$3 $switch$6$default + (i32.const 1) + ) ) - (set_local $1 - (get_local $0) + (block + (block + (unreachable) + ) ) - (return - (get_local $1) + ) + (block + (block + (block + (set_local $0 + (i32.const 2) + ) + (set_local $1 + (get_local $0) + ) + (return + (get_local $1) + ) + ) ) ) ) ) ) + (unreachable) + ) + (func $skip-empty (; 2 ;) (type $2) + (local $0 i32) + (block $block$2$break + (block + ) + (block + (br $block$2$break) + ) + ) (block - (block $block$3$break + (return) + ) + ) + (func $skip-empty-2 (; 3 ;) (type $2) + (local $0 i32) + (block $block$5$break + (block + ) + (block + (br $block$5$break) + ) + ) + (block + (block $block$4$break + (call $skip-empty) (block + (br $block$4$break) + ) + ) + (block + (block $block$2$break + (call $skip-empty) + (block + (br $block$2$break) + ) ) (block - (br $block$3$break) + (return) ) ) + ) + ) + (func $skip-empty-3 (; 4 ;) (type $2) + (local $0 i32) + (block $block$5$break + (block + ) (block + (br $block$5$break) + ) + ) + (block + (block $block$4$break + (call $skip-empty) (block - (unreachable) + (br $block$4$break) + ) + ) + (block + (block $block$2$break + (call $skip-empty) + (block + (br $block$2$break) + ) + ) + (block + (return) ) ) ) ) -) -(module - (type $0 (func (result i32))) - (func $0 (; 0 ;) (type $0) (result i32) + (func $skip-empty-4 (; 5 ;) (type $3) (param $x i32) + (local $1 i32) + (local $2 i32) + (block $block$2$break + (set_local $1 + (get_local $x) + ) + (block + (br $block$2$break) + ) + ) + (block + (return) + ) + ) + (func $skipping (; 6 ;) (type $4) (param $0 i32) (result f32) + (local $1 f32) + (local $2 f32) + (local $3 f32) + (local $4 f32) + (local $5 i32) + (block + ) + (if + (i32.const 0) + (block + (unreachable) + ) + (block + (block + (set_local $1 + (f32.const 1) + ) + (set_local $2 + (get_local $1) + ) + (set_local $3 + (get_local $2) + ) + (set_local $4 + (get_local $3) + ) + (return + (get_local $4) + ) + ) + ) + ) + ) + (func $merging (; 7 ;) (type $2) + (local $0 i32) + (block $block$2$break + (block + ) + (block + (br $block$2$break) + ) + ) + (block + (return) + ) + ) + (func $unswitch (; 8 ;) (type $2) + (local $0 i32) + (block $block$2$break + (block + ) + (block + (br $block$2$break) + ) + ) + (block + (return) + ) + ) + (func $skip-only-empty (; 9 ;) (type $2) + (local $0 i32) + (block $block$3$break + (block + ) + (if + (i32.const 1) + (block + (set_global $global + (i32.const 0) + ) + (block + (br $block$3$break) + ) + ) + (br $block$3$break) + ) + ) + (block + (return) + ) + ) + (func $skip-only-one-branch-out (; 10 ;) (type $1) (result i32) (local $0 i32) (local $1 i32) (local $2 i32) + (block $block$2$break + (block + ) + (block + (br $block$2$break) + ) + ) (block (block ) - (block $switch$1$leave - (block $switch$1$default - (block $switch$1$case$5 - (block $switch$1$case$4 - (br_table $switch$1$case$5 $switch$1$case$4 $switch$1$default - (i32.const 0) - ) + (if + (i32.const 1) + (block + (unreachable) + ) + (block + (block + (set_local $0 + (i32.const 0) + ) + (set_local $1 + (get_local $0) + ) + (return + (get_local $1) + ) + ) + ) + ) + ) + ) + (func $multipass-for-skips (; 11 ;) (type $5) (result f32) + (local $0 f32) + (local $1 f32) + (local $2 f32) + (local $3 f32) + (local $4 i32) + (block $block$7$break + (block + ) + (if + (i32.const 0) + (block + (block $block$3$break + (set_local $0 + (f32.const 9223372036854775808) ) (block - (block - (block - (nop) - (unreachable) - ) - ) + (br $block$3$break) ) ) (block (block - (block - (nop) - (unreachable) + (set_local $1 + (get_local $0) ) + (set_local $2 + (get_local $1) + ) + ) + (block + (br $block$7$break) ) ) ) (block + (set_local $2 + (f32.const 65505) + ) (block + (br $block$7$break) + ) + ) + ) + ) + (block + (block + (set_local $3 + (get_local $2) + ) + (return + (get_local $3) + ) + ) + ) + ) + (func $branch-merge-vs-replace (; 12 ;) (type $2) + (local $0 i32) + (block + ) + (if + (i32.const 0) + (block + (unreachable) + ) + (block + (return) + ) + ) + ) + (func $unswitch-amount (; 13 ;) (type $2) + (local $0 i32) + (block $block$2$break + (block + ) + (if + (i32.const -23) + (br $block$2$break) + (block + (block $block$6$break (block - (nop) ) - (block $switch$6$leave - (block $switch$6$default - (block $switch$6$case$3 - (br_table $switch$6$case$3 $switch$6$default - (i32.const 1) + (block $switch$4$leave + (block $switch$4$default + (block $switch$4$case$2 + (br_table $switch$4$case$2 $switch$4$default + (i32.const 44064) ) ) (block - (block - (block - (nop) - (unreachable) - ) - ) + (br $block$2$break) ) ) (block - (block - (block - (nop) - (set_local $0 - (i32.const 2) - ) - (set_local $1 - (get_local $0) - ) - (return - (get_local $1) - ) - ) - ) + (br $block$6$break) ) ) ) + (block + (unreachable) + ) ) - (br $switch$1$leave) ) ) - (unreachable) + (block + (return) + ) ) ) diff --git a/test/passes/flatten_rereloop.wast b/test/passes/flatten_rereloop.wast index 2584b5146..f57101dc2 100644 --- a/test/passes/flatten_rereloop.wast +++ b/test/passes/flatten_rereloop.wast @@ -1,4 +1,5 @@ (module + (global $global (mut i32) (i32.const 0)) (func $0 (result f64) (if (i32.const 0) @@ -8,9 +9,7 @@ ) (f64.const -nan:0xfffffd63e4e5a) ) -) -(module - (func $0 (result i32) + (func $1 (result i32) (block $label$8 (block $label$9 (block $label$16 @@ -32,5 +31,148 @@ ) (i32.const 2) ) + (func $skip-empty + (block $a1 + (block $a2 + (block $a3 + (block $a4 + (br $a4) + ) + (br $a3) + ) + (br $a2) + ) + (br $a1) + ) + ) + (func $skip-empty-2 + (block $a1 + (block $a2 + (block $a3 + (block $a4 + (br $a4) + ) + (call $skip-empty) + (br $a3) + ) + (call $skip-empty) + (br $a2) + ) + (br $a1) + ) + ) + (func $skip-empty-3 + (block $a1 + (block $a2 + (block $a3 + (block $a4 + (nop) + (br $a4) + (nop) + ) + (nop) + (call $skip-empty) + (nop) + (br $a3) + ) + (nop) + (call $skip-empty) + (nop) + (br $a2) + ) + (br $a1) + ) + ) + (func $skip-empty-4 (param $x i32) + (block $a1 + (block $a2 + (block $a3 + (block $a4 + (br_table $a1 $a2 $a3 $a4 $a1 $a2 $a3 $a4 (get_local $x)) + ) + (br $a3) + ) + (br $a2) + ) + (br $a1) + ) + ) + (func $skipping (param $0 i32) (result f32) + (if + (i32.const 0) + (unreachable) + ) ;; branches joining here lead to skip opportunities + (loop $label$2 (result f32) + (f32.const 1) + ) + ) + (func $merging + (if + (i32.const 0) + (return) + ;; no else, but the else ends up with a return too, and we can merge them + ) + ) + (func $unswitch + (block $label$1 + (br_table $label$1 $label$1 + (i32.const 0) + ) + ) + ) + (func $skip-only-empty + (if + (i32.const 1) + (set_global $global + (i32.const 0) + ) + ) + ) + (func $skip-only-one-branch-out (result i32) + (block $label$1 + (nop) + ) + (if + (i32.const 1) + (unreachable) ;; blocks a path through + ) + (i32.const 0) + ) + (func $multipass-for-skips (result f32) + (if (result f32) + (i32.const 0) + (block (result f32) + (block $label$2 + (br_if $label$2 + (i32.const 536870912) + ) + ) + (f32.const 9223372036854775808) + ) + (f32.const 65505) + ) + ) + (func $branch-merge-vs-replace + (if + (i32.const 0) + (unreachable) + ) + ) + (func $unswitch-amount + (block $label$1 + (if + (i32.const -23) + (nop) + (block + (block $label$4 + (br_table $label$1 $label$4 + (i32.const 44064) + ) + ) + (unreachable) + ) + ) + ) + ) ) - +;; manual TODO: merge branches, all the parts diff --git a/test/passes/rereloop.txt b/test/passes/rereloop.txt index 8d5c3eaef..fc4d5151e 100644 --- a/test/passes/rereloop.txt +++ b/test/passes/rereloop.txt @@ -5,10 +5,7 @@ (type $3 (func (param i32))) (func $trivial (; 0 ;) (type $0) (local $0 i32) - (block - (nop) - (return) - ) + (return) ) (func $trivial2 (; 1 ;) (type $0) (local $0 i32) @@ -20,16 +17,12 @@ ) (func $return-void (; 2 ;) (type $0) (local $0 i32) - (block - (return) - ) + (return) ) (func $return-val (; 3 ;) (type $1) (result i32) (local $0 i32) - (block - (return - (i32.const 1) - ) + (return + (i32.const 1) ) ) (func $ifs (; 4 ;) (type $2) (param $x i32) (result i32) @@ -44,17 +37,13 @@ (if (get_local $x) (block - (block - (return - (i32.const 2) - ) + (return + (i32.const 2) ) ) (block - (block - (return - (i32.const 3) - ) + (return + (i32.const 3) ) ) ) @@ -65,17 +54,13 @@ (if (get_local $x) (block - (block - (return - (i32.const 4) - ) + (return + (i32.const 4) ) ) (block - (block - (return - (i32.const 5) - ) + (return + (i32.const 5) ) ) ) @@ -84,88 +69,44 @@ ) (func $loops (; 5 ;) (type $3) (param $x i32) (local $1 i32) - (block $block$5$break + (block $block$6$break (block ) (if (get_local $x) - (block - (block $block$3$break - (block - ) - (block - (br $block$3$break) - ) - ) - (loop $shape$3$continue - (block - (call $trivial) - ) - (block - (br $shape$3$continue) - ) + (loop $shape$2$continue + (call $trivial) + (block + (br $shape$2$continue) ) ) - (br $block$5$break) + (br $block$6$break) ) ) (block - (block $block$6$break - (block - ) - (block - (br $block$6$break) + (block $block$8$break + (loop $shape$4$continue + (call $trivial) + (if + (get_local $x) + (br $shape$4$continue) + (br $block$8$break) + ) ) ) (block - (block $block$7$break + (block $block$11$break (loop $shape$6$continue - (block - (call $trivial) - ) + (call $trivial) (if (get_local $x) (br $shape$6$continue) - (br $block$7$break) + (br $block$11$break) ) ) ) (block - (block $block$8$break - (block - ) - (block - (br $block$8$break) - ) - ) - (block - (block $block$11$break - (loop $shape$9$continue - (block $block$9$break - (block - (call $trivial) - ) - (if - (get_local $x) - (br $block$9$break) - (br $block$11$break) - ) - ) - (block - (block - ) - (block - (br $shape$9$continue) - ) - ) - ) - ) - (block - (block - (return) - ) - ) - ) + (return) ) ) ) @@ -173,19 +114,15 @@ (func $br-out (; 6 ;) (type $3) (param $x i32) (local $1 i32) (block $block$2$break - (block - (call $br-out - (i32.const 5) - ) + (call $br-out + (i32.const 5) ) (block (br $block$2$break) ) ) (block - (block - (return) - ) + (return) ) ) (func $unreachable (; 7 ;) (type $3) (param $x i32) @@ -198,19 +135,15 @@ (br $block$2$break) (block (block $block$11$break - (block - (call $unreachable - (i32.const 5) - ) + (call $unreachable + (i32.const 5) ) (block (br $block$11$break) ) ) (block - (block - (return) - ) + (return) ) ) ) @@ -241,26 +174,15 @@ ) (func $empty-blocks (; 8 ;) (type $3) (param $x i32) (local $1 i32) - (block $block$2$break + (block $block$3$break (block ) (block - (br $block$2$break) + (br $block$3$break) ) ) (block - (block $block$3$break - (block - ) - (block - (br $block$3$break) - ) - ) - (block - (block - (return) - ) - ) + (return) ) ) (func $before-and-after (; 9 ;) (type $3) (param $x i32) @@ -292,10 +214,8 @@ (get_local $x) (br $block$3$break) (block - (block - (call $before-and-after - (i32.const 5) - ) + (call $before-and-after + (i32.const 5) ) (block (br $block$3$break) @@ -305,10 +225,8 @@ ) (block (block $block$5$break - (block - (call $before-and-after - (i32.const 6) - ) + (call $before-and-after + (i32.const 6) ) (block (br $block$5$break) @@ -316,11 +234,8 @@ ) (block (block $block$6$break - (block - (nop) - (call $before-and-after - (i32.const 7) - ) + (call $before-and-after + (i32.const 7) ) (block (br $block$6$break) @@ -328,11 +243,8 @@ ) (block (block $block$7$break - (block - (nop) - (call $before-and-after - (i32.const 8) - ) + (call $before-and-after + (i32.const 8) ) (block (br $block$7$break) @@ -341,10 +253,8 @@ (block (block $block$8$break (loop $shape$7$continue - (block - (call $before-and-after - (i32.const 9) - ) + (call $before-and-after + (i32.const 9) ) (if (get_local $x) @@ -366,10 +276,8 @@ (if (get_local $x) (block - (block - (call $before-and-after - (i32.const 12) - ) + (call $before-and-after + (i32.const 12) ) (block (br $block$10$break) @@ -380,28 +288,22 @@ ) (block (block $block$13$break - (block - (call $before-and-after - (i32.const 13) - ) + (call $before-and-after + (i32.const 13) ) (if (get_local $x) (block - (block - (call $before-and-after - (i32.const 14) - ) + (call $before-and-after + (i32.const 14) ) (block (br $block$13$break) ) ) (block - (block - (call $before-and-after - (i32.const 15) - ) + (call $before-and-after + (i32.const 15) ) (block (br $block$13$break) @@ -416,22 +318,11 @@ (if (get_local $x) (block - (block $block$15$break - (block - (call $before-and-after - (i32.const 16) - ) - ) - (block - (br $block$15$break) - ) + (call $before-and-after + (i32.const 16) ) (block - (block - ) - (block - (br $block$16$break) - ) + (br $block$16$break) ) ) (br $block$16$break) @@ -456,17 +347,15 @@ ) (block (block $block$17$break - (block - (call $before-and-after - (i32.const 20) - ) + (call $before-and-after + (i32.const 20) ) (block (br $block$17$break) ) ) (block - (block $block$20$break + (block $block$19$break (block (call $before-and-after (i32.const 21) @@ -476,47 +365,29 @@ ) ) (block - (br $block$20$break) + (br $block$19$break) ) ) (block - (block $block$19$break + (block $block$21$break (block + (call $before-and-after + (i32.const 23) + ) + (call $before-and-after + (i32.const 24) + ) ) (block - (br $block$19$break) + (br $block$21$break) ) ) (block - (block $block$22$break - (block - (call $before-and-after - (i32.const 23) - ) - (call $before-and-after - (i32.const 24) - ) - ) - (block - (br $block$22$break) - ) - ) (block - (block $block$21$break - (block - ) - (block - (br $block$21$break) - ) - ) - (block - (block - (call $before-and-after - (i32.const 25) - ) - (return) - ) + (call $before-and-after + (i32.const 25) ) + (return) ) ) ) @@ -537,34 +408,14 @@ (block $block$3$break (block ) - (block $switch$1$leave - (block $switch$1$default - (block $switch$1$case$3 - (br_table $switch$1$case$3 $switch$1$default - (get_local $x) - ) - ) - (block - (br $block$3$break) - ) - ) - (block - (block - (block - ) - (block - (br $block$3$break) - ) - ) - ) + (block + (br $block$3$break) ) ) (block (block $block$6$break - (block - (call $switch - (i32.const 1) - ) + (call $switch + (i32.const 1) ) (block $switch$3$leave (block $switch$3$default @@ -579,10 +430,8 @@ ) (block (block - (block - (call $switch - (i32.const 2) - ) + (call $switch + (i32.const 2) ) (block (br $block$6$break) @@ -593,19 +442,15 @@ ) (block (block $block$2$break - (block - (call $switch - (i32.const 3) - ) + (call $switch + (i32.const 3) ) (block (br $block$2$break) ) ) (block - (block - (return) - ) + (return) ) ) ) @@ -618,20 +463,16 @@ (if (i32.const 1) (block - (block - (drop - (i32.const 2) - ) + (drop + (i32.const 2) ) (block (br $block$4$break) ) ) (block - (block - (drop - (i32.const 3) - ) + (drop + (i32.const 3) ) (block (br $block$4$break) @@ -640,27 +481,21 @@ ) ) (block - (block - (return) - ) + (return) ) ) (func $if-br-wat (; 12 ;) (type $3) (param $x i32) (local $1 i32) (block $block$2$break (block $block$8$break - (block - (call $if-br-wat - (i32.const 0) - ) + (call $if-br-wat + (i32.const 0) ) (if (get_local $x) (block - (block - (call $if-br-wat - (i32.const 1) - ) + (call $if-br-wat + (i32.const 1) ) (block (br $block$8$break) @@ -671,29 +506,15 @@ ) (if (get_local $x) - (block - (block - ) - (block - (br $block$2$break) - ) - ) - (block - (block - ) - (block - (br $block$8$break) - ) - ) + (br $block$2$break) + (br $block$8$break) ) ) ) ) (block - (block - (call $if-br-wat - (i32.const 2) - ) + (call $if-br-wat + (i32.const 2) ) (block (br $block$2$break) @@ -724,30 +545,24 @@ ) (block (block - (block - (return - (i32.const 1) - ) + (return + (i32.const 1) ) ) ) ) (block (block - (block - (return - (i32.const 2) - ) + (return + (i32.const 2) ) ) ) ) (block (block - (block - (return - (i32.const 3) - ) + (return + (i32.const 3) ) ) ) @@ -770,37 +585,29 @@ (if (i32.const 1) (block - (block - (return) - ) + (return) ) (br $block$4$break) ) ) (block (block $block$3$break - (block - (set_global $global$0 - (i32.const 0) - ) + (set_global $global$0 + (i32.const 0) ) (block (br $block$3$break) ) ) (block - (block - (unreachable) - ) + (unreachable) ) ) ) (func $1 (; 1 ;) (type $1) (result i32) (local $0 i32) - (block - (return - (get_global $global$0) - ) + (return + (get_global $global$0) ) ) ) |