diff options
author | chriseth <c@ethdev.com> | 2016-11-23 21:50:20 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2016-11-25 23:10:02 +0800 |
commit | 612c1726d9b0dd1cb5bccd9b93ace69f6516f9ea (patch) | |
tree | 555422f4a6f50d8ea950a1ac56e53366c29ee264 /libevmasm/PeepholeOptimiser.cpp | |
parent | f2872bfa9990c483fddc72757ee764cbc79d126c (diff) | |
download | dexon-solidity-612c1726d9b0dd1cb5bccd9b93ace69f6516f9ea.tar.gz dexon-solidity-612c1726d9b0dd1cb5bccd9b93ace69f6516f9ea.tar.zst dexon-solidity-612c1726d9b0dd1cb5bccd9b93ace69f6516f9ea.zip |
Templatize.
Diffstat (limited to 'libevmasm/PeepholeOptimiser.cpp')
-rw-r--r-- | libevmasm/PeepholeOptimiser.cpp | 112 |
1 files changed, 75 insertions, 37 deletions
diff --git a/libevmasm/PeepholeOptimiser.cpp b/libevmasm/PeepholeOptimiser.cpp index 16ca9535..c8a28afc 100644 --- a/libevmasm/PeepholeOptimiser.cpp +++ b/libevmasm/PeepholeOptimiser.cpp @@ -37,6 +37,35 @@ struct OptimiserState std::back_insert_iterator<AssemblyItems> out; }; +template <class Method, size_t Arguments> +struct ApplyRule +{ +}; +template <class Method> +struct ApplyRule<Method, 3> +{ + static bool applyRule(AssemblyItems::const_iterator _in, std::back_insert_iterator<AssemblyItems> _out) + { + return Method::applySimple(_in[0], _in[1], _in[2], _out); + } +}; +template <class Method> +struct ApplyRule<Method, 2> +{ + static bool applyRule(AssemblyItems::const_iterator _in, std::back_insert_iterator<AssemblyItems> _out) + { + return Method::applySimple(_in[0], _in[1], _out); + } +}; +template <class Method> +struct ApplyRule<Method, 1> +{ + static bool applyRule(AssemblyItems::const_iterator _in, std::back_insert_iterator<AssemblyItems> _out) + { + return Method::applySimple(_in[0], _out); + } +}; + template <class Method, size_t WindowSize> struct SimplePeepholeOptimizerMethod { @@ -44,7 +73,7 @@ struct SimplePeepholeOptimizerMethod { if ( _state.i + WindowSize <= _state.items.size() && - Method::applySimple(_state.items.begin() + _state.i, _state.out) + ApplyRule<Method, WindowSize>::applyRule(_state.items.begin() + _state.i, _state.out) ) { _state.i += WindowSize; @@ -57,20 +86,20 @@ struct SimplePeepholeOptimizerMethod struct Identity: SimplePeepholeOptimizerMethod<Identity, 1> { - static bool applySimple(AssemblyItems::const_iterator _in, std::back_insert_iterator<AssemblyItems> _out) + static bool applySimple(AssemblyItem const& _item, std::back_insert_iterator<AssemblyItems> _out) { - *_out = *_in; + *_out = _item; return true; } }; struct PushPop: SimplePeepholeOptimizerMethod<PushPop, 2> { - static size_t applySimple(AssemblyItems::const_iterator _in, std::back_insert_iterator<AssemblyItems>) + static size_t applySimple(AssemblyItem const& _push, AssemblyItem const& _pop, std::back_insert_iterator<AssemblyItems>) { - auto t = _in[0].type(); - return _in[1] == Instruction::POP && ( - SemanticInformation::isDupInstruction(_in[0]) || + auto t = _push.type(); + return _pop == Instruction::POP && ( + SemanticInformation::isDupInstruction(_push) || t == Push || t == PushString || t == PushTag || t == PushSub || t == PushSubSize || t == PushProgramSize || t == PushData || t == PushLibraryAddress ); @@ -104,26 +133,55 @@ struct AddPop: SimplePeepholeOptimizerMethod<AddPop, 2> struct DoubleSwap: SimplePeepholeOptimizerMethod<DoubleSwap, 2> { - static size_t applySimple(AssemblyItems::const_iterator _in, std::back_insert_iterator<AssemblyItems>) + static size_t applySimple(AssemblyItem const& _s1, AssemblyItem const& _s2, std::back_insert_iterator<AssemblyItems>) { - return _in[0] == _in[1] && SemanticInformation::isSwapInstruction(_in[0]); + return _s1 == _s2 && SemanticInformation::isSwapInstruction(_s1); } }; struct JumpToNext: SimplePeepholeOptimizerMethod<JumpToNext, 3> { - static size_t applySimple(AssemblyItems::const_iterator _in, std::back_insert_iterator<AssemblyItems> _out) + static size_t applySimple( + AssemblyItem const& _pushTag, + AssemblyItem const& _jump, + AssemblyItem const& _tag, + std::back_insert_iterator<AssemblyItems> _out + ) + { + if ( + _pushTag.type() == PushTag && + (_jump == Instruction::JUMP || _jump == Instruction::JUMPI) && + _tag.type() == Tag && + _pushTag.data() == _tag.data() + ) + { + if (_jump == Instruction::JUMPI) + *_out = AssemblyItem(Instruction::POP, _jump.location()); + *_out = _tag; + return true; + } + else + return false; + } +}; + +struct TagConjunctions: SimplePeepholeOptimizerMethod<TagConjunctions, 3> +{ + static bool applySimple( + AssemblyItem const& _pushTag, + AssemblyItem const& _pushConstant, + AssemblyItem const& _and, + std::back_insert_iterator<AssemblyItems> _out + ) { if ( - _in[0].type() == PushTag && - (_in[1] == Instruction::JUMP || _in[1] == Instruction::JUMPI) && - _in[2].type() == Tag && - _in[0].data() == _in[2].data() + _pushTag.type() == PushTag && + _and == Instruction::AND && + _pushConstant.type() == Push && + (_pushConstant.data() & u256(0xFFFFFFFF)) == u256(0xFFFFFFFF) ) { - if (_in[1] == Instruction::JUMPI) - *_out = AssemblyItem(Instruction::POP, _in[1].location()); - *_out = _in[2]; + *_out = _pushTag; return true; } else @@ -162,26 +220,6 @@ struct UnreachableCode } }; - -struct TagConjunctions: SimplePeepholeOptimizerMethod<TagConjunctions, 3> -{ - static bool applySimple(AssemblyItems::const_iterator _in, std::back_insert_iterator<AssemblyItems> _out) - { - if ( - _in[0].type() == PushTag && - _in[2] == Instruction::AND && - _in[1].type() == Push && - (_in[1].data() & u256(0xFFFFFFFF)) == u256(0xFFFFFFFF) - ) - { - *_out = _in[0]; - return true; - } - else - return false; - } -}; - void applyMethods(OptimiserState&) { assertThrow(false, OptimizerException, "Peephole optimizer failed to apply identity."); |