mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Stabilize SSAReverser.
This commit is contained in:
parent
fd16585724
commit
29f66b2674
@ -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;
|
||||||
|
}
|
||||||
|
@ -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;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user