mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #12831 from ethereum/cse-optimization
CSE optimization
This commit is contained in:
commit
55df07f745
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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,8 +61,14 @@ 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.
|
||||
@ -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;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user