diff options
author | subtly <subtly@users.noreply.github.com> | 2015-05-11 23:40:01 +0800 |
---|---|---|
committer | subtly <subtly@users.noreply.github.com> | 2015-05-11 23:40:01 +0800 |
commit | f9955c8ba10332f9c2a674ffdfc447895c15b01a (patch) | |
tree | 8bba661f73b2e22858aece70c31eb9e9f5dfd83e /libsolidity/SolidityOptimizer.cpp | |
parent | 235cad6f19d7b40f42590fe5e20689d7ae9e8d54 (diff) | |
parent | 2cc62fbbfba89afaa2d83728ebb5b5c4488dd110 (diff) | |
download | dexon-solidity-f9955c8ba10332f9c2a674ffdfc447895c15b01a.tar dexon-solidity-f9955c8ba10332f9c2a674ffdfc447895c15b01a.tar.gz dexon-solidity-f9955c8ba10332f9c2a674ffdfc447895c15b01a.tar.bz2 dexon-solidity-f9955c8ba10332f9c2a674ffdfc447895c15b01a.tar.lz dexon-solidity-f9955c8ba10332f9c2a674ffdfc447895c15b01a.tar.xz dexon-solidity-f9955c8ba10332f9c2a674ffdfc447895c15b01a.tar.zst dexon-solidity-f9955c8ba10332f9c2a674ffdfc447895c15b01a.zip |
Merge branch 'develop' into whisper
Diffstat (limited to 'libsolidity/SolidityOptimizer.cpp')
-rw-r--r-- | libsolidity/SolidityOptimizer.cpp | 61 |
1 files changed, 54 insertions, 7 deletions
diff --git a/libsolidity/SolidityOptimizer.cpp b/libsolidity/SolidityOptimizer.cpp index 9cdaa588..3cb6a536 100644 --- a/libsolidity/SolidityOptimizer.cpp +++ b/libsolidity/SolidityOptimizer.cpp @@ -83,14 +83,28 @@ public: "\nOptimized: " + toHex(optimizedOutput)); } - AssemblyItems getCSE(AssemblyItems const& _input) + AssemblyItems addDummyLocations(AssemblyItems const& _input) { // add dummy locations to each item so that we can check that they are not deleted AssemblyItems input = _input; for (AssemblyItem& item: input) item.setLocation(SourceLocation(1, 3, make_shared<string>(""))); + return input; + } + + eth::KnownState createInitialState(AssemblyItems const& _input) + { + eth::KnownState state; + for (auto const& item: addDummyLocations(_input)) + state.feedItem(item); + return state; + } + + AssemblyItems getCSE(AssemblyItems const& _input, eth::KnownState const& _state = eth::KnownState()) + { + AssemblyItems input = addDummyLocations(_input); - eth::CommonSubexpressionEliminator cse; + eth::CommonSubexpressionEliminator cse(_state); BOOST_REQUIRE(cse.feedItems(input.begin(), input.end()) == input.end()); AssemblyItems output = cse.getOptimizedItems(); @@ -101,9 +115,13 @@ public: return output; } - void checkCSE(AssemblyItems const& _input, AssemblyItems const& _expectation) + void checkCSE( + AssemblyItems const& _input, + AssemblyItems const& _expectation, + KnownState const& _state = eth::KnownState() + ) { - AssemblyItems output = getCSE(_input); + AssemblyItems output = getCSE(_input, _state); BOOST_CHECK_EQUAL_COLLECTIONS(_expectation.begin(), _expectation.end(), output.begin(), output.end()); } @@ -113,8 +131,12 @@ public: // Running it four times should be enough for these tests. for (unsigned i = 0; i < 4; ++i) { - eth::ControlFlowGraph cfg(output); - output = cfg.optimisedItems(); + ControlFlowGraph cfg(output); + AssemblyItems optItems; + for (BasicBlock const& block: cfg.optimisedBlocks()) + copy(output.begin() + block.begin, output.begin() + block.end, + back_inserter(optItems)); + output = move(optItems); } BOOST_CHECK_EQUAL_COLLECTIONS(_expectation.begin(), _expectation.end(), output.begin(), output.end()); } @@ -231,7 +253,8 @@ BOOST_AUTO_TEST_CASE(function_calls) BOOST_AUTO_TEST_CASE(cse_intermediate_swap) { - eth::CommonSubexpressionEliminator cse; + eth::KnownState state; + eth::CommonSubexpressionEliminator cse(state); AssemblyItems input{ Instruction::SWAP1, Instruction::POP, Instruction::ADD, u256(0), Instruction::SWAP1, Instruction::SLOAD, Instruction::SWAP1, u256(100), Instruction::EXP, Instruction::SWAP1, @@ -754,6 +777,30 @@ 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(cse_with_initially_known_stack) +{ + eth::KnownState state = createInitialState(AssemblyItems{ + u256(0x12), + u256(0x20), + Instruction::ADD + }); + AssemblyItems input{ + u256(0x12 + 0x20) + }; + checkCSE(input, AssemblyItems{Instruction::DUP1}, state); +} + +BOOST_AUTO_TEST_CASE(cse_equality_on_initially_known_stack) +{ + eth::KnownState state = createInitialState(AssemblyItems{Instruction::DUP1}); + AssemblyItems input{ + Instruction::EQ + }; + AssemblyItems output = getCSE(input, state); + // check that it directly pushes 1 (true) + BOOST_CHECK(find(output.begin(), output.end(), AssemblyItem(u256(1))) != output.end()); +} + BOOST_AUTO_TEST_CASE(control_flow_graph_remove_unused) { // remove parts of the code that are unused |