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.");
|
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);
|
feedItem(*_iterator);
|
||||||
if (_iterator != _end)
|
if (_iterator != _end && chunkSize < maxChunkSize)
|
||||||
m_breakingItem = &(*_iterator++);
|
m_breakingItem = &(*_iterator++);
|
||||||
return _iterator;
|
return _iterator;
|
||||||
}
|
}
|
||||||
|
@ -23,38 +23,59 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <libevmasm/ExpressionClasses.h>
|
#include <libevmasm/ExpressionClasses.h>
|
||||||
|
|
||||||
#include <libevmasm/Assembly.h>
|
#include <libevmasm/Assembly.h>
|
||||||
#include <libevmasm/CommonSubexpressionEliminator.h>
|
#include <libevmasm/CommonSubexpressionEliminator.h>
|
||||||
#include <libevmasm/SimplificationRules.h>
|
#include <libevmasm/SimplificationRules.h>
|
||||||
|
|
||||||
|
#include <boost/container_hash/hash.hpp>
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <tuple>
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace solidity;
|
using namespace solidity;
|
||||||
using namespace solidity::evmasm;
|
using namespace solidity::evmasm;
|
||||||
using namespace solidity::langutil;
|
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, "");
|
assertThrow(!!item && !!_other.item, OptimizerException, "");
|
||||||
auto type = item->type();
|
auto type = item->type();
|
||||||
auto otherType = _other.item->type();
|
auto otherType = _other.item->type();
|
||||||
if (type != otherType)
|
if (type != otherType)
|
||||||
return type < otherType;
|
return false;
|
||||||
else if (type == Operation)
|
else if (type == Operation)
|
||||||
{
|
{
|
||||||
auto instr = item->instruction();
|
auto instr = item->instruction();
|
||||||
auto otherInstr = _other.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);
|
std::tie(otherInstr, _other.arguments, _other.sequenceNumber);
|
||||||
}
|
}
|
||||||
else
|
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::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(
|
ExpressionClasses::Id ExpressionClasses::find(
|
||||||
AssemblyItem const& _item,
|
AssemblyItem const& _item,
|
||||||
Ids const& _arguments,
|
Ids const& _arguments,
|
||||||
|
@ -24,13 +24,13 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <libsolutil/Common.h>
|
|
||||||
#include <libevmasm/AssemblyItem.h>
|
#include <libevmasm/AssemblyItem.h>
|
||||||
|
|
||||||
#include <vector>
|
#include <libsolutil/Common.h>
|
||||||
#include <map>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <set>
|
#include <unordered_set>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace solidity::langutil
|
namespace solidity::langutil
|
||||||
{
|
{
|
||||||
@ -61,9 +61,15 @@ public:
|
|||||||
/// Storage modification sequence, only used for storage and memory operations.
|
/// Storage modification sequence, only used for storage and memory operations.
|
||||||
unsigned sequenceNumber = 0;
|
unsigned sequenceNumber = 0;
|
||||||
/// Behaves as if this was a tuple of (item->type(), item->data(), arguments, sequenceNumber).
|
/// 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
|
/// Retrieves the id of the expression equivalence class resulting from the given item applied to the
|
||||||
/// given classes, might also create a new one.
|
/// given classes, might also create a new one.
|
||||||
/// @param _copyItem if true, copies the assembly item to an internal storage instead of just
|
/// @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.
|
/// Expression equivalence class representatives - we only store one item of an equivalence.
|
||||||
std::vector<Expression> m_representatives;
|
std::vector<Expression> m_representatives;
|
||||||
/// All expression ever encountered.
|
/// 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;
|
std::vector<std::shared_ptr<AssemblyItem>> m_spareAssemblyItems;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user