Stabilize SSAReverser.

This commit is contained in:
Daniel Kirchner 2019-01-17 16:11:55 +01:00
parent fd16585724
commit 29f66b2674
8 changed files with 55 additions and 11 deletions

View File

@ -134,3 +134,15 @@ void CodeCost::visit(Expression const& _expression)
++m_cost; ++m_cost;
ASTWalker::visit(_expression); 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;
}

View File

@ -77,4 +77,18 @@ private:
size_t m_cost = 0; 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;
};
} }

View File

@ -15,6 +15,7 @@
along with solidity. If not, see <http://www.gnu.org/licenses/>. along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <libyul/optimiser/SSAReverser.h> #include <libyul/optimiser/SSAReverser.h>
#include <libyul/optimiser/Metrics.h>
#include <libyul/AsmData.h> #include <libyul/AsmData.h>
#include <libdevcore/CommonData.h> #include <libdevcore/CommonData.h>
@ -22,6 +23,13 @@ using namespace std;
using namespace dev; using namespace dev;
using namespace yul; using namespace yul;
void SSAReverser::run(Block& _block)
{
AssignmentCounter assignmentCounter;
assignmentCounter(_block);
SSAReverser{assignmentCounter}(_block);
}
void SSAReverser::operator()(Block& _block) void SSAReverser::operator()(Block& _block)
{ {
walkVector(_block.statements); walkVector(_block.statements);
@ -47,7 +55,7 @@ void SSAReverser::operator()(Block& _block)
assignment->variableNames.size() == 1 && assignment->variableNames.size() == 1 &&
identifier && identifier &&
identifier->name == varDecl->variables.front().name identifier->name == varDecl->variables.front().name
) )
{ {
vector<Statement> result; vector<Statement> result;
result.emplace_back(Assignment{ result.emplace_back(Assignment{
@ -75,7 +83,10 @@ void SSAReverser::operator()(Block& _block)
if ( if (
varDecl2->variables.size() == 1 && varDecl2->variables.size() == 1 &&
identifier && 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; vector<Statement> result;

View File

@ -21,6 +21,8 @@
namespace yul namespace yul
{ {
class AssignmentCounter;
/** /**
* Reverses the SSA transformation. * 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 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. * after which the unused pruner can remove the declaration of a_1.
* *
* Prerequisites: None * Prerequisites: Disambiguator
* *
*/ */
class SSAReverser: public ASTModifier class SSAReverser: public ASTModifier
@ -62,6 +64,11 @@ class SSAReverser: public ASTModifier
public: public:
using ASTModifier::operator(); using ASTModifier::operator();
void operator()(Block& _block) override; void operator()(Block& _block) override;
static void run(Block& _block);
private:
SSAReverser(AssignmentCounter const& _assignmentCounter): m_assignmentCounter(_assignmentCounter) {}
AssignmentCounter const& m_assignmentCounter;
}; };
} }

View File

@ -90,7 +90,7 @@ void OptimiserSuite::run(
CommonSubexpressionEliminator{_dialect}(ast); CommonSubexpressionEliminator{_dialect}(ast);
UnusedPruner::runUntilStabilised(_dialect, ast, reservedIdentifiers); UnusedPruner::runUntilStabilised(_dialect, ast, reservedIdentifiers);
SSAReverser{}(ast); SSAReverser::run(ast);
CommonSubexpressionEliminator{_dialect}(ast); CommonSubexpressionEliminator{_dialect}(ast);
UnusedPruner::runUntilStabilised(_dialect, ast, reservedIdentifiers); UnusedPruner::runUntilStabilised(_dialect, ast, reservedIdentifiers);
@ -130,7 +130,7 @@ void OptimiserSuite::run(
ExpressionJoiner::run(ast); ExpressionJoiner::run(ast);
UnusedPruner::runUntilStabilised(_dialect, ast); UnusedPruner::runUntilStabilised(_dialect, ast);
SSAReverser{}(ast); SSAReverser::run(ast);
CommonSubexpressionEliminator{_dialect}(ast); CommonSubexpressionEliminator{_dialect}(ast);
UnusedPruner::runUntilStabilised(_dialect, ast, reservedIdentifiers); UnusedPruner::runUntilStabilised(_dialect, ast, reservedIdentifiers);

View File

@ -227,7 +227,7 @@ bool YulOptimizerTest::run(ostream& _stream, string const& _linePrefix, bool con
else if (m_optimizerStep == "ssaReverser") else if (m_optimizerStep == "ssaReverser")
{ {
disambiguate(); disambiguate();
SSAReverser{}(*m_ast); SSAReverser::run(*m_ast);
} }
else if (m_optimizerStep == "ssaAndBack") else if (m_optimizerStep == "ssaAndBack")
{ {
@ -237,7 +237,7 @@ bool YulOptimizerTest::run(ostream& _stream, string const& _linePrefix, bool con
SSATransform::run(*m_ast, nameDispenser); SSATransform::run(*m_ast, nameDispenser);
RedundantAssignEliminator::run(*m_dialect, *m_ast); RedundantAssignEliminator::run(*m_dialect, *m_ast);
// reverse SSA // reverse SSA
SSAReverser{}(*m_ast); SSAReverser::run(*m_ast);
CommonSubexpressionEliminator{*m_dialect}(*m_ast); CommonSubexpressionEliminator{*m_dialect}(*m_ast);
UnusedPruner::runUntilStabilised(*m_dialect, *m_ast); UnusedPruner::runUntilStabilised(*m_dialect, *m_ast);
} }

View File

@ -10,9 +10,9 @@
// ---- // ----
// ssaAndBack // ssaAndBack
// { // {
// let a := mload(0) // let a_1 := mload(0)
// let b := mload(a) // let b_2 := mload(a_1)
// let a_3 := mload(b) // let a_3 := mload(b_2)
// let b_4 := mload(a_3) // let b_4 := mload(a_3)
// let a_5 := mload(b_4) // let a_5 := mload(b_4)
// let b_6 := mload(a_5) // let b_6 := mload(a_5)

View File

@ -190,7 +190,7 @@ public:
EquivalentFunctionCombiner::run(*m_ast); EquivalentFunctionCombiner::run(*m_ast);
break; break;
case 'V': case 'V':
SSAReverser{}(*m_ast); SSAReverser::run(*m_ast);
break; break;
default: default:
cout << "Unknown option." << endl; cout << "Unknown option." << endl;