diff options
author | Daniel Kirchner <daniel@ekpyron.org> | 2018-09-14 21:49:55 +0800 |
---|---|---|
committer | chriseth <chris@ethereum.org> | 2018-09-18 20:28:21 +0800 |
commit | a1d73a7befd2f3d72c18d4cb539edab5111c681f (patch) | |
tree | bd440467d4d2f4d2c275b47f51057933cac2aaef /libevmasm | |
parent | 06ffcd0502c1c06788bec9b1e1e4db3f7c42ed4d (diff) | |
download | dexon-solidity-a1d73a7befd2f3d72c18d4cb539edab5111c681f.tar.gz dexon-solidity-a1d73a7befd2f3d72c18d4cb539edab5111c681f.tar.zst dexon-solidity-a1d73a7befd2f3d72c18d4cb539edab5111c681f.zip |
Split simplification rules into two functions.
Diffstat (limited to 'libevmasm')
-rw-r--r-- | libevmasm/ExpressionClasses.cpp | 1 | ||||
-rw-r--r-- | libevmasm/RuleList.h | 47 | ||||
-rw-r--r-- | libevmasm/SimplificationRules.cpp | 21 | ||||
-rw-r--r-- | libevmasm/SimplificationRules.h | 6 |
4 files changed, 62 insertions, 13 deletions
diff --git a/libevmasm/ExpressionClasses.cpp b/libevmasm/ExpressionClasses.cpp index 69b33ec5..42a1819a 100644 --- a/libevmasm/ExpressionClasses.cpp +++ b/libevmasm/ExpressionClasses.cpp @@ -184,6 +184,7 @@ string ExpressionClasses::fullDAGToString(ExpressionClasses::Id _id) const ExpressionClasses::Id ExpressionClasses::tryToSimplify(Expression const& _expr) { static Rules rules; + assertThrow(rules.isInitialized(), OptimizerException, "Rule list not properly initialized."); if ( !_expr.item || diff --git a/libevmasm/RuleList.h b/libevmasm/RuleList.h index 0573856b..874a8929 100644 --- a/libevmasm/RuleList.h +++ b/libevmasm/RuleList.h @@ -44,12 +44,11 @@ template <class S> S modWorkaround(S const& _a, S const& _b) return (S)(bigint(_a) % bigint(_b)); } -/// @returns a list of simplification rules given certain match placeholders. -/// A, B and C should represent constants, X and Y arbitrary expressions. -/// The simplifications should never change the order of evaluation of -/// arbitrary operations. +// This part of simplificationRuleList below was split out to prevent +// stack overflows in the JavaScript optimizer for emscripten builds +// that affected certain browser versions. template <class Pattern> -std::vector<SimplificationRule<Pattern>> simplificationRuleList( +std::vector<SimplificationRule<Pattern>> simplificationRuleListPart1( Pattern A, Pattern B, Pattern C, @@ -57,8 +56,7 @@ std::vector<SimplificationRule<Pattern>> simplificationRuleList( Pattern Y ) { - std::vector<SimplificationRule<Pattern>> rules; - rules += std::vector<SimplificationRule<Pattern>>{ + return std::vector<SimplificationRule<Pattern>> { // arithmetic on constants {{Instruction::ADD, {A, B}}, [=]{ return A.d() + B.d(); }, false}, {{Instruction::MUL, {A, B}}, [=]{ return A.d() * B.d(); }, false}, @@ -162,6 +160,22 @@ std::vector<SimplificationRule<Pattern>> simplificationRuleList( {{Instruction::OR, {X, {Instruction::NOT, {X}}}}, [=]{ return ~u256(0); }, true}, {{Instruction::OR, {{Instruction::NOT, {X}}, X}}, [=]{ return ~u256(0); }, true}, }; +} + + +// This part of simplificationRuleList below was split out to prevent +// stack overflows in the JavaScript optimizer for emscripten builds +// that affected certain browser versions. +template <class Pattern> +std::vector<SimplificationRule<Pattern>> simplificationRuleListPart2( + Pattern A, + Pattern B, + Pattern, + Pattern X, + Pattern Y +) +{ + std::vector<SimplificationRule<Pattern>> rules; // Replace MOD X, <power-of-two> with AND X, <power-of-two> - 1 for (size_t i = 0; i < 256; ++i) @@ -292,5 +306,24 @@ std::vector<SimplificationRule<Pattern>> simplificationRuleList( return rules; } +/// @returns a list of simplification rules given certain match placeholders. +/// A, B and C should represent constants, X and Y arbitrary expressions. +/// The simplifications should never change the order of evaluation of +/// arbitrary operations. +template <class Pattern> +std::vector<SimplificationRule<Pattern>> simplificationRuleList( + Pattern A, + Pattern B, + Pattern C, + Pattern X, + Pattern Y +) +{ + std::vector<SimplificationRule<Pattern>> rules; + rules += simplificationRuleListPart1(A, B, C, X, Y); + rules += simplificationRuleListPart2(A, B, C, X, Y); + return rules; +} + } } diff --git a/libevmasm/SimplificationRules.cpp b/libevmasm/SimplificationRules.cpp index 504dbc24..ba13a611 100644 --- a/libevmasm/SimplificationRules.cpp +++ b/libevmasm/SimplificationRules.cpp @@ -21,16 +21,19 @@ * Container for equivalence classes of expressions for use in common subexpression elimination. */ +#include <libevmasm/SimplificationRules.h> + #include <libevmasm/ExpressionClasses.h> -#include <utility> -#include <functional> -#include <boost/range/adaptor/reversed.hpp> -#include <boost/noncopyable.hpp> #include <libevmasm/Assembly.h> #include <libevmasm/CommonSubexpressionEliminator.h> -#include <libevmasm/SimplificationRules.h> - #include <libevmasm/RuleList.h> +#include <libdevcore/Assertions.h> + +#include <boost/range/adaptor/reversed.hpp> +#include <boost/noncopyable.hpp> + +#include <utility> +#include <functional> using namespace std; using namespace dev; @@ -54,6 +57,11 @@ SimplificationRule<Pattern> const* Rules::findFirstMatch( return nullptr; } +bool Rules::isInitialized() const +{ + return !m_rules[byte(Instruction::ADD)].empty(); +} + void Rules::addRules(std::vector<SimplificationRule<Pattern>> const& _rules) { for (auto const& r: _rules) @@ -82,6 +90,7 @@ Rules::Rules() Y.setMatchGroup(5, m_matchGroups); addRules(simplificationRuleList(A, B, C, X, Y)); + assertThrow(isInitialized(), OptimizerException, "Rule list not properly initialized."); } Pattern::Pattern(Instruction _instruction, std::vector<Pattern> const& _arguments): diff --git a/libevmasm/SimplificationRules.h b/libevmasm/SimplificationRules.h index 53f7e595..fbe5a2b0 100644 --- a/libevmasm/SimplificationRules.h +++ b/libevmasm/SimplificationRules.h @@ -26,6 +26,8 @@ #include <libevmasm/ExpressionClasses.h> #include <libevmasm/SimplificationRule.h> +#include <boost/noncopyable.hpp> + #include <functional> #include <vector> @@ -53,6 +55,10 @@ public: ExpressionClasses const& _classes ); + /// Checks whether the rulelist is non-empty. This is usually enforced + /// by the constructor, but we had some issues with static initialization. + bool isInitialized() const; + private: void addRules(std::vector<SimplificationRule<Pattern>> const& _rules); void addRule(SimplificationRule<Pattern> const& _rule); |