diff options
author | Daniel Kirchner <daniel@ekpyron.org> | 2019-01-17 23:11:55 +0800 |
---|---|---|
committer | Daniel Kirchner <daniel@ekpyron.org> | 2019-01-18 04:05:32 +0800 |
commit | 29f66b267426535c7ffe8eda09c3b50888dcdfc0 (patch) | |
tree | c7429889d3050b4d13770e29e2c430c03955c68c /libyul | |
parent | fd1658572463a246f602ae0fe161430429daa9e0 (diff) | |
download | dexon-solidity-29f66b267426535c7ffe8eda09c3b50888dcdfc0.tar dexon-solidity-29f66b267426535c7ffe8eda09c3b50888dcdfc0.tar.gz dexon-solidity-29f66b267426535c7ffe8eda09c3b50888dcdfc0.tar.bz2 dexon-solidity-29f66b267426535c7ffe8eda09c3b50888dcdfc0.tar.lz dexon-solidity-29f66b267426535c7ffe8eda09c3b50888dcdfc0.tar.xz dexon-solidity-29f66b267426535c7ffe8eda09c3b50888dcdfc0.tar.zst dexon-solidity-29f66b267426535c7ffe8eda09c3b50888dcdfc0.zip |
Stabilize SSAReverser.
Diffstat (limited to 'libyul')
-rw-r--r-- | libyul/optimiser/Metrics.cpp | 12 | ||||
-rw-r--r-- | libyul/optimiser/Metrics.h | 14 | ||||
-rw-r--r-- | libyul/optimiser/SSAReverser.cpp | 15 | ||||
-rw-r--r-- | libyul/optimiser/SSAReverser.h | 9 | ||||
-rw-r--r-- | libyul/optimiser/Suite.cpp | 4 |
5 files changed, 49 insertions, 5 deletions
diff --git a/libyul/optimiser/Metrics.cpp b/libyul/optimiser/Metrics.cpp index df919682..e13940aa 100644 --- a/libyul/optimiser/Metrics.cpp +++ b/libyul/optimiser/Metrics.cpp @@ -134,3 +134,15 @@ void CodeCost::visit(Expression const& _expression) ++m_cost; ASTWalker::visit(_expression); } + +void AssignmentCounter::operator()(Assignment const& _assignment) +{ + for (auto const& variable: _assignment.variableNames) + ++m_assignmentCounters[variable.name]; +} + +size_t AssignmentCounter::assignmentCount(YulString _name) const +{ + auto it = m_assignmentCounters.find(_name); + return (it == m_assignmentCounters.end()) ? 0 : it->second; +} diff --git a/libyul/optimiser/Metrics.h b/libyul/optimiser/Metrics.h index 03e1b62a..5364646e 100644 --- a/libyul/optimiser/Metrics.h +++ b/libyul/optimiser/Metrics.h @@ -77,4 +77,18 @@ private: size_t m_cost = 0; }; +/** + * Counts the number of assignments to every variable. + * Only works after running the Disambiguator. + */ +class AssignmentCounter: public ASTWalker +{ +public: + using ASTWalker::operator(); + void operator()(Assignment const& _assignment) override; + std::size_t assignmentCount(YulString _name) const; +private: + std::map<YulString, size_t> m_assignmentCounters; +}; + } diff --git a/libyul/optimiser/SSAReverser.cpp b/libyul/optimiser/SSAReverser.cpp index 2cfa3d58..6548ebb5 100644 --- a/libyul/optimiser/SSAReverser.cpp +++ b/libyul/optimiser/SSAReverser.cpp @@ -15,6 +15,7 @@ along with solidity. If not, see <http://www.gnu.org/licenses/>. */ #include <libyul/optimiser/SSAReverser.h> +#include <libyul/optimiser/Metrics.h> #include <libyul/AsmData.h> #include <libdevcore/CommonData.h> @@ -22,6 +23,13 @@ using namespace std; using namespace dev; using namespace yul; +void SSAReverser::run(Block& _block) +{ + AssignmentCounter assignmentCounter; + assignmentCounter(_block); + SSAReverser{assignmentCounter}(_block); +} + void SSAReverser::operator()(Block& _block) { walkVector(_block.statements); @@ -47,7 +55,7 @@ void SSAReverser::operator()(Block& _block) assignment->variableNames.size() == 1 && identifier && identifier->name == varDecl->variables.front().name - ) + ) { vector<Statement> result; result.emplace_back(Assignment{ @@ -75,7 +83,10 @@ void SSAReverser::operator()(Block& _block) if ( varDecl2->variables.size() == 1 && identifier && - identifier->name == varDecl->variables.front().name + identifier->name == varDecl->variables.front().name && ( + m_assignmentCounter.assignmentCount(varDecl2->variables.front().name) > + m_assignmentCounter.assignmentCount(varDecl->variables.front().name) + ) ) { vector<Statement> result; diff --git a/libyul/optimiser/SSAReverser.h b/libyul/optimiser/SSAReverser.h index 34b61647..67abeb56 100644 --- a/libyul/optimiser/SSAReverser.h +++ b/libyul/optimiser/SSAReverser.h @@ -21,6 +21,8 @@ namespace yul { +class AssignmentCounter; + /** * Reverses the SSA transformation. * @@ -54,7 +56,7 @@ namespace yul * After that the CSE can replace references of a_1 by references to a, * after which the unused pruner can remove the declaration of a_1. * - * Prerequisites: None + * Prerequisites: Disambiguator * */ class SSAReverser: public ASTModifier @@ -62,6 +64,11 @@ class SSAReverser: public ASTModifier public: using ASTModifier::operator(); void operator()(Block& _block) override; + + static void run(Block& _block); +private: + SSAReverser(AssignmentCounter const& _assignmentCounter): m_assignmentCounter(_assignmentCounter) {} + AssignmentCounter const& m_assignmentCounter; }; } diff --git a/libyul/optimiser/Suite.cpp b/libyul/optimiser/Suite.cpp index 63931554..8cf6e104 100644 --- a/libyul/optimiser/Suite.cpp +++ b/libyul/optimiser/Suite.cpp @@ -90,7 +90,7 @@ void OptimiserSuite::run( CommonSubexpressionEliminator{_dialect}(ast); UnusedPruner::runUntilStabilised(_dialect, ast, reservedIdentifiers); - SSAReverser{}(ast); + SSAReverser::run(ast); CommonSubexpressionEliminator{_dialect}(ast); UnusedPruner::runUntilStabilised(_dialect, ast, reservedIdentifiers); @@ -130,7 +130,7 @@ void OptimiserSuite::run( ExpressionJoiner::run(ast); UnusedPruner::runUntilStabilised(_dialect, ast); - SSAReverser{}(ast); + SSAReverser::run(ast); CommonSubexpressionEliminator{_dialect}(ast); UnusedPruner::runUntilStabilised(_dialect, ast, reservedIdentifiers); |