aboutsummaryrefslogtreecommitdiffstats
path: root/SolidityOptimizer.cpp
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2015-03-24 21:53:15 +0800
committerchriseth <c@ethdev.com>2015-03-30 18:03:28 +0800
commit1391b58e53cdc3f163b81a972f0e798b5f7a8980 (patch)
treec6d578ad6ad251f4b286a8e24dd371276f91dd70 /SolidityOptimizer.cpp
parent735c02c468de32b4f91c59794039b67ab29a8170 (diff)
downloaddexon-solidity-1391b58e53cdc3f163b81a972f0e798b5f7a8980.tar
dexon-solidity-1391b58e53cdc3f163b81a972f0e798b5f7a8980.tar.gz
dexon-solidity-1391b58e53cdc3f163b81a972f0e798b5f7a8980.tar.bz2
dexon-solidity-1391b58e53cdc3f163b81a972f0e798b5f7a8980.tar.lz
dexon-solidity-1391b58e53cdc3f163b81a972f0e798b5f7a8980.tar.xz
dexon-solidity-1391b58e53cdc3f163b81a972f0e798b5f7a8980.tar.zst
dexon-solidity-1391b58e53cdc3f163b81a972f0e798b5f7a8980.zip
Storage access optimisation.
Diffstat (limited to 'SolidityOptimizer.cpp')
-rw-r--r--SolidityOptimizer.cpp180
1 files changed, 180 insertions, 0 deletions
diff --git a/SolidityOptimizer.cpp b/SolidityOptimizer.cpp
index 2d5cff7a..de4cac8f 100644
--- a/SolidityOptimizer.cpp
+++ b/SolidityOptimizer.cpp
@@ -303,6 +303,186 @@ BOOST_AUTO_TEST_CASE(cse_associativity2)
checkCSE(input, {Instruction::DUP2, Instruction::DUP2, Instruction::ADD, u256(5), Instruction::ADD});
}
+BOOST_AUTO_TEST_CASE(cse_storage)
+{
+ AssemblyItems input{
+ u256(0),
+ Instruction::SLOAD,
+ u256(0),
+ Instruction::SLOAD,
+ Instruction::ADD,
+ u256(0),
+ Instruction::SSTORE
+ };
+ checkCSE(input, {
+ u256(0),
+ Instruction::DUP1,
+ Instruction::SLOAD,
+ Instruction::DUP1,
+ Instruction::ADD,
+ Instruction::SWAP1,
+ Instruction::SSTORE
+ });
+}
+
+BOOST_AUTO_TEST_CASE(cse_noninterleaved_storage)
+{
+ // two stores to the same location should be replaced by only one store, even if we
+ // read in the meantime
+ AssemblyItems input{
+ u256(7),
+ Instruction::DUP2,
+ Instruction::SSTORE,
+ Instruction::DUP1,
+ Instruction::SLOAD,
+ u256(8),
+ Instruction::DUP3,
+ Instruction::SSTORE
+ };
+ checkCSE(input, {
+ u256(8),
+ Instruction::DUP2,
+ Instruction::SSTORE,
+ u256(7)
+ });
+}
+
+BOOST_AUTO_TEST_CASE(cse_interleaved_storage)
+{
+ // stores and reads to/from two unknown locations, should not optimize away the first store
+ AssemblyItems input{
+ u256(7),
+ Instruction::DUP2,
+ Instruction::SSTORE, // store to "DUP1"
+ Instruction::DUP2,
+ Instruction::SLOAD, // read from "DUP2", might be equal to "DUP1"
+ u256(0),
+ Instruction::DUP3,
+ Instruction::SSTORE // store different value to "DUP1"
+ };
+ checkCSE(input, input);
+}
+
+BOOST_AUTO_TEST_CASE(cse_interleaved_storage_same_value)
+{
+ // stores and reads to/from two unknown locations, should not optimize away the first store
+ // but it should optimize away the second, since we already know the value will be the same
+ AssemblyItems input{
+ u256(7),
+ Instruction::DUP2,
+ Instruction::SSTORE, // store to "DUP1"
+ Instruction::DUP2,
+ Instruction::SLOAD, // read from "DUP2", might be equal to "DUP1"
+ u256(6),
+ u256(1),
+ Instruction::ADD,
+ Instruction::DUP3,
+ Instruction::SSTORE // store same value to "DUP1"
+ };
+ checkCSE(input, {
+ u256(7),
+ Instruction::DUP2,
+ Instruction::SSTORE,
+ Instruction::DUP2,
+ Instruction::SLOAD
+ });
+}
+
+BOOST_AUTO_TEST_CASE(cse_interleaved_storage_at_known_location)
+{
+ // stores and reads to/from two known locations, should optimize away the first store,
+ // because we know that the location is different
+ AssemblyItems input{
+ u256(0x70),
+ u256(1),
+ Instruction::SSTORE, // store to 1
+ u256(2),
+ Instruction::SLOAD, // read from 2, is different from 1
+ u256(0x90),
+ u256(1),
+ Instruction::SSTORE // store different value at 1
+ };
+ checkCSE(input, {
+ u256(2),
+ Instruction::SLOAD,
+ u256(0x90),
+ u256(1),
+ Instruction::SSTORE
+ });
+}
+
+BOOST_AUTO_TEST_CASE(cse_interleaved_storage_at_known_location_offset)
+{
+ // stores and reads to/from two locations which are known to be different,
+ // should optimize away the first store, because we know that the location is different
+ AssemblyItems input{
+ u256(0x70),
+ Instruction::DUP2,
+ u256(1),
+ Instruction::ADD,
+ Instruction::SSTORE, // store to "DUP1"+1
+ Instruction::DUP1,
+ u256(2),
+ Instruction::ADD,
+ Instruction::SLOAD, // read from "DUP1"+2, is different from "DUP1"+1
+ u256(0x90),
+ Instruction::DUP3,
+ u256(1),
+ Instruction::ADD,
+ Instruction::SSTORE // store different value at "DUP1"+1
+ };
+ checkCSE(input, {
+ u256(2),
+ Instruction::DUP2,
+ Instruction::ADD,
+ Instruction::SLOAD,
+ u256(0x90),
+ u256(1),
+ Instruction::DUP4,
+ Instruction::ADD,
+ Instruction::SSTORE
+ });
+}
+
+BOOST_AUTO_TEST_CASE(cse_deep_stack)
+{
+ AssemblyItems input{
+ Instruction::ADD,
+ Instruction::SWAP1,
+ Instruction::POP,
+ Instruction::SWAP8,
+ Instruction::POP,
+ Instruction::SWAP8,
+ Instruction::POP,
+ Instruction::SWAP8,
+ Instruction::SWAP5,
+ Instruction::POP,
+ Instruction::POP,
+ Instruction::POP,
+ Instruction::POP,
+ Instruction::POP,
+ };
+ checkCSE(input, {
+ Instruction::SWAP4,
+ Instruction::SWAP12,
+ Instruction::SWAP3,
+ Instruction::SWAP11,
+ Instruction::POP,
+ Instruction::SWAP1,
+ Instruction::SWAP3,
+ Instruction::ADD,
+ Instruction::SWAP8,
+ Instruction::POP,
+ Instruction::SWAP6,
+ Instruction::POP,
+ Instruction::POP,
+ Instruction::POP,
+ Instruction::POP,
+ Instruction::POP,
+ Instruction::POP,
+ });
+}
+
BOOST_AUTO_TEST_SUITE_END()
}