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