mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	Track unreachable variables globally instead of per function.
This commit is contained in:
		
							parent
							
								
									756e21a888
								
							
						
					
					
						commit
						0b87849bcb
					
				| @ -66,14 +66,13 @@ struct MemoryOffsetAllocator | ||||
| 		if (unreachableVariables.count(_function)) | ||||
| 		{ | ||||
| 			yulAssert(!slotAllocations.count(_function), ""); | ||||
| 			auto& assignedSlots = slotAllocations[_function]; | ||||
| 			for (YulString variable: unreachableVariables.at(_function)) | ||||
| 				if (variable.empty()) | ||||
| 				{ | ||||
| 					// TODO: Too many function arguments or return parameters.
 | ||||
| 				} | ||||
| 				else | ||||
| 					assignedSlots[variable] = requiredSlots++; | ||||
| 					slotAllocations[variable] = requiredSlots++; | ||||
| 		} | ||||
| 
 | ||||
| 		return slotsRequiredForFunction[_function] = requiredSlots; | ||||
| @ -82,7 +81,7 @@ struct MemoryOffsetAllocator | ||||
| 	map<YulString, set<YulString>> const& unreachableVariables; | ||||
| 	map<YulString, set<YulString>> const& callGraph; | ||||
| 
 | ||||
| 	map<YulString, map<YulString, uint64_t>> slotAllocations{}; | ||||
| 	map<YulString, uint64_t> slotAllocations{}; | ||||
| 	map<YulString, uint64_t> slotsRequiredForFunction{}; | ||||
| }; | ||||
| 
 | ||||
|  | ||||
| @ -54,7 +54,7 @@ vector<Statement> generateMemoryStore( | ||||
| void StackToMemoryMover::run( | ||||
| 	OptimiserStepContext& _context, | ||||
| 	u256 _reservedMemory, | ||||
| 	map<YulString, map<YulString, uint64_t>> const& _memorySlots, | ||||
| 	map<YulString, uint64_t> const& _memorySlots, | ||||
| 	uint64_t _numRequiredSlots, | ||||
| 	Block& _block | ||||
| ) | ||||
| @ -66,7 +66,7 @@ void StackToMemoryMover::run( | ||||
| StackToMemoryMover::StackToMemoryMover( | ||||
| 	OptimiserStepContext& _context, | ||||
| 	u256 _reservedMemory, | ||||
| 	map<YulString, map<YulString, uint64_t>> const& _memorySlots, | ||||
| 	map<YulString, uint64_t> const& _memorySlots, | ||||
| 	uint64_t _numRequiredSlots | ||||
| ): | ||||
| m_context(_context), | ||||
| @ -80,41 +80,25 @@ m_nameDispenser(_context.dispenser) | ||||
| 		evmDialect && evmDialect->providesObjectAccess(), | ||||
| 		"StackToMemoryMover can only be run on objects using the EVMDialect with object access." | ||||
| 	); | ||||
| 
 | ||||
| 	if (m_memorySlots.count(YulString{})) | ||||
| 		// If the global scope contains variables to be moved, start with those as if it were a function.
 | ||||
| 		m_currentFunctionMemorySlots = &m_memorySlots.at(YulString{}); | ||||
| } | ||||
| 
 | ||||
| void StackToMemoryMover::operator()(FunctionDefinition& _functionDefinition) | ||||
| { | ||||
| 	if (m_memorySlots.count(_functionDefinition.name)) | ||||
| 	{ | ||||
| 		map<YulString, uint64_t> const* saved = m_currentFunctionMemorySlots; | ||||
| 		m_currentFunctionMemorySlots = &m_memorySlots.at(_functionDefinition.name); | ||||
| 		for (TypedName const& param: _functionDefinition.parameters + _functionDefinition.returnVariables) | ||||
| 			if (m_currentFunctionMemorySlots->count(param.name)) | ||||
| 			{ | ||||
| 				// TODO: we cannot handle function parameters yet.
 | ||||
| 				m_currentFunctionMemorySlots = saved; | ||||
| 				return; | ||||
| 			} | ||||
| 		ASTModifier::operator()(_functionDefinition); | ||||
| 		m_currentFunctionMemorySlots = saved; | ||||
| 	} | ||||
| 	for (TypedName const& param: _functionDefinition.parameters + _functionDefinition.returnVariables) | ||||
| 		if (m_memorySlots.count(param.name)) | ||||
| 		{ | ||||
| 			// TODO: we cannot handle function parameters yet.
 | ||||
| 			return; | ||||
| 		} | ||||
| 	ASTModifier::operator()(_functionDefinition); | ||||
| } | ||||
| 
 | ||||
| void StackToMemoryMover::operator()(Block& _block) | ||||
| { | ||||
| 	using OptionalStatements = std::optional<vector<Statement>>; | ||||
| 	if (!m_currentFunctionMemorySlots) | ||||
| 	{ | ||||
| 		ASTModifier::operator()(_block); | ||||
| 		return; | ||||
| 	} | ||||
| 	auto containsVariableNeedingEscalation = [&](auto const& _variables) { | ||||
| 		return util::contains_if(_variables, [&](auto const& var) { | ||||
| 			return m_currentFunctionMemorySlots->count(var.name); | ||||
| 			return m_memorySlots.count(var.name); | ||||
| 		}); | ||||
| 	}; | ||||
| 	auto rewriteAssignmentOrVariableDeclaration = [&]( | ||||
| @ -138,7 +122,7 @@ void StackToMemoryMover::operator()(Block& _block) | ||||
| 			YulString tempVarName = m_nameDispenser.newName(var.name); | ||||
| 			tempDecl.variables.emplace_back(TypedName{var.location, tempVarName, {}}); | ||||
| 
 | ||||
| 			if (m_currentFunctionMemorySlots->count(var.name)) | ||||
| 			if (m_memorySlots.count(var.name)) | ||||
| 				memoryAssignments += generateMemoryStore( | ||||
| 					m_context.dialect, | ||||
| 					_loc, | ||||
| @ -203,7 +187,7 @@ void StackToMemoryMover::visit(Expression& _expression) | ||||
| { | ||||
| 	if ( | ||||
| 		Identifier* identifier = std::get_if<Identifier>(&_expression); | ||||
| 		identifier && m_currentFunctionMemorySlots && m_currentFunctionMemorySlots->count(identifier->name) | ||||
| 		identifier && m_memorySlots.count(identifier->name) | ||||
| 	) | ||||
| 	{ | ||||
| 		BuiltinFunction const* memoryLoadFunction = m_context.dialect.memoryLoadFunction(m_context.dialect.defaultType); | ||||
| @ -227,8 +211,8 @@ void StackToMemoryMover::visit(Expression& _expression) | ||||
| 
 | ||||
| YulString StackToMemoryMover::memoryOffset(YulString _variable) | ||||
| { | ||||
| 	yulAssert(m_currentFunctionMemorySlots, ""); | ||||
| 	uint64_t slot = m_currentFunctionMemorySlots->at(_variable); | ||||
| 	yulAssert(m_memorySlots.count(_variable), ""); | ||||
| 	uint64_t slot = m_memorySlots.at(_variable); | ||||
| 	yulAssert(slot < m_numRequiredSlots, ""); | ||||
| 	return YulString{util::toCompactHexWithPrefix(m_reservedMemory + 32 * (m_numRequiredSlots - slot - 1))}; | ||||
| } | ||||
|  | ||||
| @ -90,7 +90,7 @@ public: | ||||
| 	static void run( | ||||
| 		OptimiserStepContext& _context, | ||||
| 		u256 _reservedMemory, | ||||
| 		std::map<YulString, std::map<YulString, uint64_t>> const& _memorySlots, | ||||
| 		std::map<YulString, uint64_t> const& _memorySlots, | ||||
| 		uint64_t _numRequiredSlots, | ||||
| 		Block& _block | ||||
| 	); | ||||
| @ -103,7 +103,7 @@ private: | ||||
| 	StackToMemoryMover( | ||||
| 		OptimiserStepContext& _context, | ||||
| 		u256 _reservedMemory, | ||||
| 		std::map<YulString, std::map<YulString, uint64_t>> const& _memorySlots, | ||||
| 		std::map<YulString, uint64_t> const& _memorySlots, | ||||
| 		uint64_t _numRequiredSlots | ||||
| 	); | ||||
| 
 | ||||
| @ -112,10 +112,9 @@ private: | ||||
| 
 | ||||
| 	OptimiserStepContext& m_context; | ||||
| 	u256 m_reservedMemory; | ||||
| 	std::map<YulString, std::map<YulString, uint64_t>> const& m_memorySlots; | ||||
| 	std::map<YulString, uint64_t> const& m_memorySlots; | ||||
| 	uint64_t m_numRequiredSlots = 0; | ||||
| 	NameDispenser& m_nameDispenser; | ||||
| 	std::map<YulString, uint64_t> const* m_currentFunctionMemorySlots = nullptr; | ||||
| }; | ||||
| 
 | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user