using namespace std;
using namespace dev;
using namespace dev::julia;
using namespace dev::julia::test;
using namespace dev::solidity;
namespace
{
string inlinableFunctions(string const& _source)
{
auto ast = disambiguate(_source);
InlinableExpressionFunctionFinder funFinder;
funFinder(ast);
return boost::algorithm::join(
funFinder.inlinableFunctions() | boost::adaptors::map_keys,
","
);
}
string inlineFunctions(string const& _source, bool _yul = true)
{
auto ast = disambiguate(_source, _yul);
ExpressionInliner(ast).run();
return assembly::AsmPrinter(_yul)(ast);
}
string fullInline(string const& _source, bool _yul = true)
{
Block ast = disambiguate(_source, _yul);
(FunctionHoister{})(ast);
(FunctionGrouper{})(ast);\
FullInliner(ast).run();
return assembly::AsmPrinter(_yul)(ast);
}
}
BOOST_AUTO_TEST_SUITE(YulInlinableFunctionFilter)
BOOST_AUTO_TEST_CASE(smoke_test)
{
BOOST_CHECK_EQUAL(inlinableFunctions("{ }"), "");
}
BOOST_AUTO_TEST_CASE(simple)
{
BOOST_CHECK_EQUAL(inlinableFunctions("{ function f() -> x:u256 { x := 2:u256 } }"), "f");
BOOST_CHECK_EQUAL(inlinableFunctions("{"
"function g(a:u256) -> b:u256 { b := a }"
"function f() -> x:u256 { x := g(2:u256) }"
"}"), "f,g");
}
BOOST_AUTO_TEST_CASE(simple_inside_structures)
{
BOOST_CHECK_EQUAL(inlinableFunctions("{"
"switch 2:u256 "
"case 2:u256 {"
"function g(a:u256) -> b:u256 { b := a }"
"function f() -> x:u256 { x := g(2:u256) }"
"}"
"}"), "f,g");
BOOST_CHECK_EQUAL(inlinableFunctions("{"
"for {"
"function g(a:u256) -> b:u256 { b := a }"
"} 1:u256 {"
"function f() -> x:u256 { x := g(2:u256) }"
"}"
"{"
"function h() -> y:u256 { y := 2:u256 }"
"}"
"}"), "f,g,h");
}
BOOST_AUTO_TEST_CASE(negative)
{
BOOST_CHECK_EQUAL(inlinableFunctions("{ function f() -> x:u256 { } }"), "");
BOOST_CHECK_EQUAL(inlinableFunctions("{ function f() -> x:u256 { x := 2:u256 {} } }"), "");
BOOST_CHECK_EQUAL(inlinableFunctions("{ function f() -> x:u256 { x := f() } }"), "");
BOOST_CHECK_EQUAL(inlinableFunctions("{ function f() -> x:u256 { x := x } }"), "");
BOOST_CHECK_EQUAL(inlinableFunctions("{ function f() -> x:u256, y:u256 { x := 2:u256 } }"), "");
BOOST_CHECK_EQUAL(inlinableFunctions(
"{ function g() -> x:u256, y:u256 {} function f(y:u256) -> x:u256 { x,y := g() } }"), "");
BOOST_CHECK_EQUAL(inlinableFunctions("{ function f(y:u256) -> x:u256 { y := 2:u256 } }"), "");
}
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_SUITE(YulFunctionInliner)
BOOST_AUTO_TEST_CASE(simple)
{
BOOST_CHECK_EQUAL(
inlineFunctions("{ function f() -> x:u256 { x := 2:u256 } let y:u256 := f() }"),
format("{ function f() -> x:u256 { x := 2:u256 } let y:u256 := 2:u256 }")
);
}
BOOST_AUTO_TEST_CASE(with_args)
{
BOOST_CHECK_EQUAL(
inlineFunctions("{ function f(a:u256) -> x:u256 { x := a } let y:u256 := f(7:u256) }"),
format("{ function f(a:u256) -> x:u256 { x := a } let y:u256 := 7:u256 }")
);
}
BOOST_AUTO_TEST_CASE(no_inline_with_mload)
{
// Does not inline because mload could be moved out of sequence
BOOST_CHECK_EQUAL(
inlineFunctions("{ function f(a) -> x { x := a } let y := f(mload(2)) }", false),
format("{ function f(a) -> x { x := a } let y := f(mload(2)) }", false)
);
}
BOOST_AUTO_TEST_CASE(no_move_with_side_effects)
{
// The calls to g and h cannot be moved because g and h are not movable. Therefore, the call
// to f is not inlined.
BOOST_CHECK_EQUAL(
inlineFunctions("{"
"function f(a, b) -> x { x := add(b, a) }"
"function g() -> y { y := mload(0) mstore(0, 4) }"
"function h() -> z { mstore(0, 4) z := mload(0) }"
"let r := f(g(), h())"
"}", false),
format("{"
"function f(a, b) -> x { x := add(b, a) }"
"function g() -> y { y := mload(0) mstore(0, 4) }"
"function h() -> z { mstore(0, 4) z := mload(0) }"
"let r := f(g(), h())"
"}", false)
);
}
BOOST_AUTO_TEST_CASE(complex_with_evm)
{
BOOST_CHECK_EQUAL(
inlineFunctions("{ function f(a) -> x { x := add(a, a) } let y := f(calldatasize()) }", false),
format("{ function f(a) -> x { x := add(a, a) } let y := add(calldatasize(), calldatasize()) }", false)
);
}
BOOST_AUTO_TEST_CASE(double_calls)
{
BOOST_CHECK_EQUAL(
inlineFunctions("{"
"function f(a) -> x { x := add(a, a) }"
"function g(b, c) -> y { y := mul(mload(c), f(b)) }"
"let y := g(calldatasize(), 7)"
"}", false),
format("{"
"function f(a) -> x { x := add(a, a) }"
"function g(b, c) -> y { y := mul(mload(c), add(b, b)) }"
"let y_1 := mul(mload(7), add(calldatasize(), calldatasize()))"
"}", false)
);
}
BOOST_AUTO_TEST_CASE(double_recursive_calls)
{
BOOST_CHECK_EQUAL(
inlineFunctions("{"
"function f(a, r) -> x { x := g(a, g(r, r)) }"
"function g(b, s) -> y { y := f(b, f(s, s)) }"
"let y := g(calldatasize(), 7)"
"}", false),
format("{"
"function f(a, r) -> x { x := g(a, f(r, f(r, r))) }"
"function g(b, s) -> y { y := f(b, g(s, f(s, f(s, s))))}"
"let y_1 := f(calldatasize(), g(7, f(7, f(7, 7))))"
"}", false)
);
}
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_SUITE(YulFullInliner)
BOOST_AUTO_TEST_CASE(simple)
{
BOOST_CHECK_EQUAL(
fullInline("{"
"function f(a) -> x { let r := mul(a, a) x := add(r, r) }"
"let y := add(f(sload(mload(2))), mload(7))"
"}", false),
format("{"
"{"
"let _1 := mload(7)"
"let f_a := sload(mload(2))"
"let f_x"
"{"
"let f_r := mul(f_a, f_a)"
"f_x := add(f_r, f_r)"
"}"
"let y := add(f_x, _1)"
"}"
"function f(a) -> x"
"{"
"let r := mul(a, a)"
"x := add(r, r)"
"}"
"}", false)
);
}
BOOST_AUTO_TEST_CASE(multi_fun)
{
BOOST_CHECK_EQUAL(
fullInline("{"
"function f(a) -> x { x := add(a, a) }"
"function g(b, c) -> y { y := mul(mload(c), f(b)) }"
"let y := g(f(3), 7)"
"}", false),
format("{"
"{"
"let g_c := 7 "
"let f_a_1 := 3 "
"let f_x_1 "
"{ f_x_1 := add(f_a_1, f_a_1) } "
"let g_y "
"{"
"let g_f_a := f_x_1 "
"let g_f_x "
"{"
"g_f_x := add(g_f_a, g_f_a)"
"}"
"g_y := mul(mload(g_c), g_f_x)"
"}"
"let y_1 := g_y"
"}"
"function f(a) -> x"
"{"
"x := add(a, a)"
"}"
"function g(b, c) -> y"
"{"
"let f_a := b "
"let f_x "
"{"
"f_x := add(f_a, f_a)"
"}"
"y := mul(mload(c), f_x)"
"}"
"}", false)
);
}
BOOST_AUTO_TEST_CASE(move_up_rightwards_arguments)
{
BOOST_CHECK_EQUAL(
fullInline("{"
"function f(a, b, c) -> x { x := add(a, b) x := mul(x, c) }"
"let y := add(mload(1), add(f(mload(2), mload(3), mload(4)), mload(5)))"
"}", false),
format("{"
"{"
"let _1 := mload(5)"
"let f_c := mload(4)"
"let f_b := mload(3)"
"let f_a := mload(2)"
"let f_x"
"{"
"f_x := add(f_a, f_b)"
"f_x := mul(f_x, f_c)"
"}"
"let y := add(mload(1), add(f_x, _1))"
"}"
"function f(a, b, c) -> x"
"{"
"x := add(a, b)"
"x := mul(x, c)"
"}"
"}", false)
);
}
BOOST_AUTO_TEST_CASE(pop_result)
{
// This tests that `pop(r)` is removed.
BOOST_CHECK_EQUAL(
fullInline("{"
"function f(a) -> x { let r := mul(a, a) x := add(r, r) }"
"pop(add(f(7), 2))"
"}", false),
format("{"
"{"
"let _1 := 2 "
"let f_a := 7 "
"let f_x "
"{"
"let f_r := mul(f_a, f_a) "
"f_x := add(f_r, f_r)"
"}"
"{"
"}"
"}"
"function f(a) -> x"
"{"
"let r := mul(a, a) "
"x := add(r, r)"
"}"
"}", false)
);
}
BOOST_AUTO_TEST_SUITE_END()
6 04:11:49 +0800'>2007-02-061 | -2/+2 |
* | - Reflects the update of the Japanese message file. | clsung | 2007-02-05 | 2 | -4/+5 |
* | Put distfile on master_site_local | lofi | 2007-02-05 | 1 | -1/+2 |
* | - Update to 2.49 | rafan | 2007-02-04 | 2 | -5/+5 |
* | fix build (by using libtool:15) with recent CURRENTs where objformat went away | oliver | 2007-02-04 | 2 | -1/+1 |
* | - Update to 2.4.4 | rafan | 2007-02-03 | 2 | -4/+4 |
* | - Update to 20070124 | acm | 2007-02-02 | 5 | -84/+78 |
* | Use libtool port instead of included version to avoid objformat a.out botch | kris | 2007-02-01 | 3 | -0/+3 |
* | - add category gnustep | dinoex | 2007-02-01 | 1 | -1/+1 |
* | - Fix spelling of CONFLICTS | pav | 2007-01-31 | 2 | -2/+2 |
* | - Remove support for a.out format and PORTOBJFORMAT variable from individual | pav | 2007-01-30 | 2 | -17/+2 |
* | enhance the description | oliver | 2007-01-29 | 1 | -3/+5 |
* | Use libtool port instead of included one to avoid objformat a.out botch | kris | 2007-01-28 | 2 | -0/+2 |
* | - Update to 1.7.1 | miwi | 2007-01-28 | 8 | -36/+82 |
* | - Add PORTSCOUT variable. | shaun | 2007-01-26 | 1 | -1/+3 |
* | Update to 0.7.0. | mezz | 2007-01-26 | 4 | -18/+13 |
* | - Added files/ patch-api_model.c, patch-prnt_hpijs_configure | nivit | 2007-01-25 | 24 | -492/+654 |
* | - Update to 20070120 | acm | 2007-01-25 | 2 | -5/+6 |
* | - Changed master site (the old one has disappeared) | nivit | 2007-01-24 | 1 | -2/+3 |
* | - Update to 5.2.4 | miwi | 2007-01-24 | 2 | -4/+4 |
* | - Fix build on gcc 4. These two changes are stole from print/ghostscript-afpl. | rafan | 2007-01-23 | 4 | -34/+576 |
* | - Fix build on gcc 4. Patch is stealed from print/ghostscript-afpl, | rafan | 2007-01-23 | 2 | -0/+540 |
* | - Update to 2.14 | rafan | 2007-01-23 | 2 | -4/+4 |
* | Import xfce 4.4 | oliver | 2007-01-23 | 4 | -74/+63 |
* | - Generalize libgcj dependency line | pav | 2007-01-22 | 1 | -1/+1 |
* | Undo the "verbosity reduction" hunk, that slipped with the last upgrade. | mi | 2007-01-21 | 5 | -35/+35 |
* | - Fix previous revision to DTRT | pav | 2007-01-19 | 1 | -1/+1 |
* | - Allow usage of gcc 4.2 and up | pav | 2007-01-19 | 1 | -2/+2 |
* | - Update to 1.4.3 | miwi | 2007-01-18 | 15 | -85/+345 |
* | - update to 0.81 | itetcu | 2007-01-18 | 5 | -176/+74 |
* | Update to 7.0.9. Various security vulnerabilities have been fixed. | hrs | 2007-01-18 | 18 | -673/+32 |
* | - update to 5.3 | itetcu | 2007-01-18 | 2 | -10/+7 |
* | - update to 1.3.2 | itetcu | 2007-01-18 | 2 | -5/+5 |
* | - Update to 2.48 | miwi | 2007-01-14 | 3 | -6/+7 |
* | - Update to 20070108 | acm | 2007-01-14 | 2 | -4/+4 |
* | - update to use new bsd.gnustep.mk | dinoex | 2007-01-13 | 1 | -3/+2 |
* | - Use USE_ICONV instead of LIB_DEPENDS | rafan | 2007-01-12 | 1 | -4/+4 |
* | - Update to 1.21.1 | erwin | 2007-01-06 | 4 | -17/+51 |
* | 2007-01-04 net/tund: distfile disappeared and has no homepage | miwi | 2007-01-06 | 8 | -148/+0 |
* | 2007-01-01 graphics/teddy: No new releases in the past 4 years | miwi | 2007-01-06 | 36 | -1691/+0 |
* | 2006-12-01 net-p2p/gnome-btdownload: does not run with BitTorrent 4.x yet | miwi | 2007-01-06 | 7 | -273/+0 |
* | - Update to 0.9.5 | rafan | 2007-01-05 | 3 | -6/+11 |
* | upgrade to 5.2.3 | ijliao | 2007-01-05 | 2 | -5/+5 |
* | Took a lot of nice patches from Ubuntu Linux to make both of ports work better | mezz | 2007-01-05 | 21 | -7/+1949 |
* | Resurrect print/latex-pgf and print/latex-beamer and update | hrs | 2007-01-05 | 8 | -0/+1094 |
* | - Chase security/gnutls update | novel | 2007-01-02 | 1 | -2/+2 |
* | -Update to 0.6.7. | mezz | 2007-01-02 | 3 | -8/+10 |
* | - Update to 0.16.0. | mezz | 2007-01-02 | 1 | -0/+2 |
* | Grab MAINTAINER | ahze | 2007-01-01 | 1 | -1/+1 |
* | - Be compatible with Debian's font famliy name for | rafan | 2007-01-01 | 2 | -2/+6 |
* | ReportLab is a software library that lets you directly create | miwi | 2006-12-31 | 8 | -0/+883 |
* | - Update to 2.13 | rafan | 2006-12-30 | 2 | -4/+4 |
* | - add option WITH_I18N | dinoex | 2006-12-30 | 3 | -0/+46 |
* | - RUN_DEPEND on Ghostscript which besides bringing in some needed fonts also | itetcu | 2006-12-29 | 2 | -28/+20 |
* | Use SF.net mirrors for MASTER_SITES | itetcu | 2006-12-27 | 1 | -1/+3 |
* | - Update to 20061224 | acm | 2006-12-27 | 3 | -6/+5 |
* | Mark BROKEN: fails to fetch. | linimon | 2006-12-27 | 1 | -0/+2 |
* | -Update to final 5.0.0. | mezz | 2006-12-25 | 6 | -152/+96 |
* | Update to 0.6.6 | ahze | 2006-12-25 | 2 | -5/+4 |
* | Update MAINTAINER email address of my ports | nox | 2006-12-24 | 1 | -1/+1 |
* | - honor PTHREAD_LIBS | dinoex | 2006-12-22 | 1 | -39/+40 |
* | In preparation to deprecate shells/bash2: | bsam | 2006-12-22 | 1 | -1/+1 |
* | - Don't install t1asm, depends on t1utils instead | rafan | 2006-12-21 | 3 | -1/+12 |
* | - move RUN_DEPENDS to BUILD_DEPENDS | dinoex | 2006-12-18 | 1 | -2/+2 |
* | - drop empty file | dinoex | 2006-12-18 | 1 | -1/+0 |
* | - Update to 20061212 | acm | 2006-12-16 | 4 | -8/+16 |
* | - Update to 20061214 | acm | 2006-12-16 | 5 | -25/+24 |
* | - Add backup MASTER_SITES | miwi | 2006-12-14 | 1 | -1/+3 |
* | - Honor CC in the lib subdir | jmz | 2006-12-14 | 7 | -1/+101 |
* | Update the ftp/curl port to 7.16.0. | roam | 2006-12-13 | 1 | -1/+2 |
* | Remove expired ports: | vd | 2006-12-13 | 41 | -1021/+0 |
* | Remove expired leaf ports: | vd | 2006-12-12 | 8 | -399/+0 |
* | - take maintainership | dinoex | 2006-12-10 | 2 | -6/+3 |
* | Fix the typo in my last commit. I accidentally committed the wrong version | gabor | 2006-12-10 | 1 | -1/+1 |
* | - Updated email address in my ports | nivit | 2006-12-10 | 4 | -4/+4 |
* | - Fix fetching | gabor | 2006-12-09 | 3 | -11/+6 |
* | - Update to 2.5.5 | gabor | 2006-12-09 | 3 | -51/+15 |
* | - Respect X11BASE | rafan | 2006-12-09 | 1 | -0/+1 |
* | - Fix Build | miwi | 2006-12-09 | 1 | -1/+1 |
* | This package used to extract the revision and file information | miwi | 2006-12-07 | 5 | -0/+64 |
* | Reset asa@agava.com after several months of inactivity and no response to | linimon | 2006-12-06 | 2 | -2/+2 |
* | - Update to 1.2.7 | sat | 2006-12-06 | 5 | -610/+793 |
* | - Update to 8.15.3 | miwi | 2006-12-06 | 7 | -32/+595 |
* | - Update to 1.5.0 | miwi | 2006-12-06 | 7 | -83/+31 |
* | - Deprecate | erwin | 2006-12-05 | 1 | -0/+3 |
* | - Deprecate | erwin | 2006-12-05 | 1 | -0/+3 |
* | - Deprecate | erwin | 2006-12-05 | 1 | -0/+3 |
* | Correct path to Compress::Zlib.pm after recent p5-Compress-Zlib update. | demon | 2006-12-03 | 1 | -1/+1 |
* | - Update to current snapshot (should fix compatiblity problems with the new | stas | 2006-12-03 | 1 | -4/+10 |
* | - Update to 2.12 | rafan | 2006-11-29 | 2 | -4/+4 |
* | - Respect X11BASE | miwi | 2006-11-28 | 2 | -6/+15 |
* | Make it compatible with a nonstandard X11BASE (untested). | jmz | 2006-11-24 | 1 | -4/+2 |
* | - Update to 2.4.3 | pav | 2006-11-24 | 3 | -13/+10 |
* | Remove expired leaf port: | vd | 2006-11-22 | 5 | -57/+0 |
* | - Update to 3.6.2 | miwi | 2006-11-16 | 7 | -85/+18 |
* | - Do not overwrite configuration file. Bump PORTREVISION | rafan | 2006-11-14 | 2 | -13/+23 |
* | - Do not install t1asm, depending on print/t1utils instead. | rafan | 2006-11-13 | 2 | -3/+5 |
* | Remove expired ports: | vd | 2006-11-09 | 4 | -40/+0 |
* | Mark BROKEN and DEPRECATED, the project was born dead. | ale | 2006-11-08 | 1 | -0/+4 |
* | - Marked BROKEN on FreeBSD 7 as it doesn't compile. | alepulver | 2006-11-08 | 1 | -6/+23 |
* | Update my email address in all ports that I maintain. | laszlof | 2006-11-07 | 1 | -1/+1 |
* | Update to 2.1.2 release. | ale | 2006-11-07 | 2 | -4/+4 |
* | - Update to 20061031 | acm | 2006-11-07 | 2 | -4/+4 |
* | - Update to 20061031 | acm | 2006-11-07 | 3 | -8/+17 |
* | PDF generation using only PHP, without requiring any external libraries. | miwi | 2006-11-06 | 4 | -0/+32 |
* | - Update to 1.3.3.4 | miwi | 2006-11-06 | 6 | -176/+194 |
* | INSTALLS_SHLIB -> USE_LDCONFIG. | mezz | 2006-11-05 | 1 | -1/+2 |
* | -INSTALLS_SHLIB -> USE_LDCONFIG.[1] | mezz | 2006-11-05 | 1 | -2/+4 |
* | - Some tweaks, no patch required | rafan | 2006-11-03 | 3 | -26/+13 |
* | Update to 2.1.1 release. | ale | 2006-11-01 | 2 | -5/+4 |
* | Update to 7.0.0p3 release and make it fetchable again. | ale | 2006-11-01 | 2 | -5/+5 |
* | - Pass maintainership to submitter | miwi | 2006-11-01 | 1 | -1/+1 |
* | - Update to 4.7.0 | rafan | 2006-10-31 | 3 | -31/+39 |
* | GSPdf is a Postscript and Pdf Viewer for GNUstep. | dinoex | 2006-10-31 | 5 | -0/+56 |
* | - Update to 2.11 | rafan | 2006-10-31 | 2 | -4/+4 |
* | - Update to 20061010 | acm | 2006-10-20 | 5 | -8/+164 |
* | Restore major 7.0.0p1 PORTVERSION to make scripts happy. | ale | 2006-10-16 | 1 | -4/+3 |
* | Fix fetching. | ale | 2006-10-15 | 1 | -2/+3 |
* | Update to 7.0.0p1 release and make it fetchable again. | ale | 2006-10-15 | 2 | -5/+5 |
* | Correct a typo when WITH_CJK is defined. | marcus | 2006-10-15 | 1 | -2/+2 |
* | Chase the GNOME X11BASE to LOCALBASE move, and fix the build with the | marcus | 2006-10-14 | 7 | -15/+73 |
* | Presenting GNOME 2.16.1 for FreeBSD. This release represents a massive | marcus | 2006-10-14 | 12 | -160/+113 |
* | - Unbreak | erwin | 2006-10-12 | 1 | -7/+9 |