diff options
author | subtly <subtly@users.noreply.github.com> | 2015-04-17 08:54:28 +0800 |
---|---|---|
committer | subtly <subtly@users.noreply.github.com> | 2015-04-17 08:54:28 +0800 |
commit | 106a7d10ccfa08d5e6b83a1ecae6fce0226f2c94 (patch) | |
tree | e1c2284800888dec27eed3d470b447b622e86703 | |
parent | 14adc795ac6efc48de5f63cd9b459ee96e968795 (diff) | |
parent | 0f9b0f3bc4fbebb2ab956f0178ec82442065b1bc (diff) | |
download | dexon-solidity-106a7d10ccfa08d5e6b83a1ecae6fce0226f2c94.tar dexon-solidity-106a7d10ccfa08d5e6b83a1ecae6fce0226f2c94.tar.gz dexon-solidity-106a7d10ccfa08d5e6b83a1ecae6fce0226f2c94.tar.bz2 dexon-solidity-106a7d10ccfa08d5e6b83a1ecae6fce0226f2c94.tar.lz dexon-solidity-106a7d10ccfa08d5e6b83a1ecae6fce0226f2c94.tar.xz dexon-solidity-106a7d10ccfa08d5e6b83a1ecae6fce0226f2c94.tar.zst dexon-solidity-106a7d10ccfa08d5e6b83a1ecae6fce0226f2c94.zip |
Merge branch 'develop' into discoveryEndpoints
-rw-r--r-- | SolidityOptimizer.cpp | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/SolidityOptimizer.cpp b/SolidityOptimizer.cpp index f523847f..f57380ac 100644 --- a/SolidityOptimizer.cpp +++ b/SolidityOptimizer.cpp @@ -28,6 +28,7 @@ #include <boost/lexical_cast.hpp> #include <test/solidityExecutionFramework.h> #include <libevmcore/CommonSubexpressionEliminator.h> +#include <libevmcore/ControlFlowGraph.h> #include <libevmcore/Assembly.h> using namespace std; @@ -96,6 +97,18 @@ public: BOOST_CHECK_EQUAL_COLLECTIONS(_expectation.begin(), _expectation.end(), output.begin(), output.end()); } + void checkCFG(AssemblyItems const& _input, AssemblyItems const& _expectation) + { + AssemblyItems output = _input; + // Running it four times should be enough for these tests. + for (unsigned i = 0; i < 4; ++i) + { + eth::ControlFlowGraph cfg(output); + output = cfg.optimisedItems(); + } + BOOST_CHECK_EQUAL_COLLECTIONS(_expectation.begin(), _expectation.end(), output.begin(), output.end()); + } + protected: Address m_optimizedContract; Address m_nonOptimizedContract; @@ -731,6 +744,73 @@ BOOST_AUTO_TEST_CASE(cse_sha3_twice_same_content_noninterfering_store_in_between BOOST_CHECK_EQUAL(1, count(output.begin(), output.end(), AssemblyItem(Instruction::SHA3))); } +BOOST_AUTO_TEST_CASE(control_flow_graph_remove_unused) +{ + // remove parts of the code that are unused + AssemblyItems input{ + AssemblyItem(PushTag, 1), + Instruction::JUMP, + u256(7), + AssemblyItem(Tag, 1), + }; + checkCFG(input, {}); +} + +BOOST_AUTO_TEST_CASE(control_flow_graph_remove_unused_loop) +{ + AssemblyItems input{ + AssemblyItem(PushTag, 3), + Instruction::JUMP, + AssemblyItem(Tag, 1), + u256(7), + AssemblyItem(PushTag, 2), + Instruction::JUMP, + AssemblyItem(Tag, 2), + u256(8), + AssemblyItem(PushTag, 1), + Instruction::JUMP, + AssemblyItem(Tag, 3), + u256(11) + }; + checkCFG(input, {u256(11)}); +} + +BOOST_AUTO_TEST_CASE(control_flow_graph_reconnect_single_jump_source) +{ + // move code that has only one unconditional jump source + AssemblyItems input{ + u256(1), + AssemblyItem(PushTag, 1), + Instruction::JUMP, + AssemblyItem(Tag, 2), + u256(2), + AssemblyItem(PushTag, 3), + Instruction::JUMP, + AssemblyItem(Tag, 1), + u256(3), + AssemblyItem(PushTag, 2), + Instruction::JUMP, + AssemblyItem(Tag, 3), + u256(4), + }; + checkCFG(input, {u256(1), u256(3), u256(2), u256(4)}); +} + +BOOST_AUTO_TEST_CASE(control_flow_graph_do_not_remove_returned_to) +{ + // do not remove parts that are "returned to" + AssemblyItems input{ + AssemblyItem(PushTag, 1), + AssemblyItem(PushTag, 2), + Instruction::JUMP, + AssemblyItem(Tag, 2), + Instruction::JUMP, + AssemblyItem(Tag, 1), + u256(2) + }; + checkCFG(input, {u256(2)}); +} + BOOST_AUTO_TEST_SUITE_END() } |