Merge pull request #12831 from ethereum/cse-optimization

CSE optimization
This commit is contained in:
Damian Wechman 2022-05-19 11:00:41 +02:00 committed by GitHub
commit 55df07f745
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 46 additions and 13 deletions

View File

@ -179,9 +179,15 @@ AssemblyItemIterator CommonSubexpressionEliminator::feedItems(
)
{
assertThrow(!m_breakingItem, OptimizerException, "Invalid use of CommonSubexpressionEliminator.");
for (; _iterator != _end && !SemanticInformation::breaksCSEAnalysisBlock(*_iterator, _msizeImportant); ++_iterator)
unsigned const maxChunkSize = 2000;
unsigned chunkSize = 0;
for (
;
_iterator != _end && !SemanticInformation::breaksCSEAnalysisBlock(*_iterator, _msizeImportant) && chunkSize < maxChunkSize;
++_iterator, ++chunkSize
)
feedItem(*_iterator);
if (_iterator != _end)
if (_iterator != _end && chunkSize < maxChunkSize)
m_breakingItem = &(*_iterator++);
return _iterator;
}

View File

@ -23,38 +23,59 @@
*/
#include <libevmasm/ExpressionClasses.h>
#include <libevmasm/Assembly.h>
#include <libevmasm/CommonSubexpressionEliminator.h>
#include <libevmasm/SimplificationRules.h>
#include <boost/container_hash/hash.hpp>
#include <functional>
#include <tuple>
#include <limits>
#include <tuple>
using namespace std;
using namespace solidity;
using namespace solidity::evmasm;
using namespace solidity::langutil;
bool ExpressionClasses::Expression::operator<(ExpressionClasses::Expression const& _other) const
bool ExpressionClasses::Expression::operator==(ExpressionClasses::Expression const& _other) const
{
assertThrow(!!item && !!_other.item, OptimizerException, "");
auto type = item->type();
auto otherType = _other.item->type();
if (type != otherType)
return type < otherType;
return false;
else if (type == Operation)
{
auto instr = item->instruction();
auto otherInstr = _other.item->instruction();
return std::tie(instr, arguments, sequenceNumber) <
return std::tie(instr, arguments, sequenceNumber) ==
std::tie(otherInstr, _other.arguments, _other.sequenceNumber);
}
else
return std::tie(item->data(), arguments, sequenceNumber) <
return std::tie(item->data(), arguments, sequenceNumber) ==
std::tie(_other.item->data(), _other.arguments, _other.sequenceNumber);
}
std::size_t ExpressionClasses::Expression::ExpressionHash::operator()(Expression const& _expression) const
{
assertThrow(!!_expression.item, OptimizerException, "");
std::size_t seed = 0;
auto type = _expression.item->type();
boost::hash_combine(seed, type);
if (type == Operation)
boost::hash_combine(seed, _expression.item->instruction());
else
boost::hash_combine(seed, _expression.item->data());
boost::hash_range(seed, _expression.arguments.begin(), _expression.arguments.end());
boost::hash_combine(seed, _expression.sequenceNumber);
return seed;
}
ExpressionClasses::Id ExpressionClasses::find(
AssemblyItem const& _item,
Ids const& _arguments,

View File

@ -24,13 +24,13 @@
#pragma once
#include <libsolutil/Common.h>
#include <libevmasm/AssemblyItem.h>
#include <vector>
#include <map>
#include <libsolutil/Common.h>
#include <memory>
#include <set>
#include <unordered_set>
#include <vector>
namespace solidity::langutil
{
@ -61,9 +61,15 @@ public:
/// Storage modification sequence, only used for storage and memory operations.
unsigned sequenceNumber = 0;
/// Behaves as if this was a tuple of (item->type(), item->data(), arguments, sequenceNumber).
bool operator<(Expression const& _other) const;
bool operator==(Expression const& _other) const;
struct ExpressionHash
{
std::size_t operator()(Expression const& _expression) const;
};
};
/// Retrieves the id of the expression equivalence class resulting from the given item applied to the
/// given classes, might also create a new one.
/// @param _copyItem if true, copies the assembly item to an internal storage instead of just
@ -122,7 +128,7 @@ private:
/// Expression equivalence class representatives - we only store one item of an equivalence.
std::vector<Expression> m_representatives;
/// All expression ever encountered.
std::set<Expression> m_expressions;
std::unordered_set<Expression, Expression::ExpressionHash> m_expressions;
std::vector<std::shared_ptr<AssemblyItem>> m_spareAssemblyItems;
};