mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	YulStack: When Yul optimization is not requested, run Yul optimizer with a minimal sequence instead of disabling it
This commit is contained in:
		
							parent
							
								
									dff774d82f
								
							
						
					
					
						commit
						25be38905f
					
				| @ -11,6 +11,7 @@ Compiler Features: | ||||
|  * Parser: Introduce ``pragma experimental solidity``, which will enable an experimental language mode that in particular has no stability guarantees between non-breaking releases and is not suited for production use. | ||||
|  * Standard JSON Interface: Add ``ast`` file-level output for Yul input. | ||||
|  * Standard JSON Interface: Add ``irAst`` and ``irOptimizedAst`` contract-level outputs for Solidity input, providing AST in compact JSON format for IR and optimized IR. | ||||
|  * Yul Optimizer: Stack-to-memory mover is now enabled by default whenever possible for via IR code generation and pure Yul compilation. | ||||
| 
 | ||||
| 
 | ||||
| Bugfixes: | ||||
|  | ||||
| @ -304,7 +304,7 @@ Input Description | ||||
|               // optimization-sequence:clean-up-sequence. For more information see | ||||
|               // "The Optimizer > Selecting Optimizations". | ||||
|               // This field is optional, and if not provided, the default sequences for both | ||||
|               // optimization and clean-up are used. If only one of the options is provivded | ||||
|               // optimization and clean-up are used. If only one of the sequences is provided | ||||
|               // the other will not be run. | ||||
|               // If only the delimiter ":" is provided then neither the optimization nor the clean-up | ||||
|               // sequence will be run. | ||||
|  | ||||
| @ -103,8 +103,8 @@ struct OptimiserSettings | ||||
| 			case OptimisationPreset::Minimal: return minimal(); | ||||
| 			case OptimisationPreset::Standard: return standard(); | ||||
| 			case OptimisationPreset::Full: return full(); | ||||
| 			default: solAssert(false, ""); | ||||
| 		} | ||||
| 		util::unreachable(); | ||||
| 	} | ||||
| 
 | ||||
| 	bool operator==(OptimiserSettings const& _other) const | ||||
|  | ||||
| @ -86,9 +86,6 @@ bool YulStack::parseAndAnalyze(std::string const& _sourceName, std::string const | ||||
| 
 | ||||
| void YulStack::optimize() | ||||
| { | ||||
| 	if (!m_optimiserSettings.runYulOptimiser) | ||||
| 		return; | ||||
| 
 | ||||
| 	yulAssert(m_analysisSuccessful, "Analysis was not successful."); | ||||
| 
 | ||||
| 	m_analysisSuccessful = false; | ||||
| @ -159,13 +156,15 @@ void YulStack::optimize(Object& _object, bool _isCreation) | ||||
| 	unique_ptr<GasMeter> meter; | ||||
| 	if (EVMDialect const* evmDialect = dynamic_cast<EVMDialect const*>(&dialect)) | ||||
| 		meter = make_unique<GasMeter>(*evmDialect, _isCreation, m_optimiserSettings.expectedExecutionsPerDeployment); | ||||
| 
 | ||||
| 	OptimiserSuite::run( | ||||
| 		dialect, | ||||
| 		meter.get(), | ||||
| 		_object, | ||||
| 		m_optimiserSettings.optimizeStackAllocation, | ||||
| 		m_optimiserSettings.yulOptimiserSteps, | ||||
| 		m_optimiserSettings.yulOptimiserCleanupSteps, | ||||
| 		// Defaults are the minimum necessary to avoid running into "Stack too deep" constantly.
 | ||||
| 		m_optimiserSettings.runYulOptimiser ? m_optimiserSettings.optimizeStackAllocation : true, | ||||
| 		m_optimiserSettings.runYulOptimiser ? m_optimiserSettings.yulOptimiserSteps : "u", | ||||
| 		m_optimiserSettings.runYulOptimiser ? m_optimiserSettings.yulOptimiserCleanupSteps : "", | ||||
| 		_isCreation ? nullopt : make_optional(m_optimiserSettings.expectedExecutionsPerDeployment), | ||||
| 		{} | ||||
| 	); | ||||
| @ -231,7 +230,12 @@ YulStack::assembleEVMWithDeployed(optional<string_view> _deployName) const | ||||
| 
 | ||||
| 	evmasm::Assembly assembly(m_evmVersion, true, {}); | ||||
| 	EthAssemblyAdapter adapter(assembly); | ||||
| 	compileEVM(adapter, m_optimiserSettings.optimizeStackAllocation); | ||||
| 
 | ||||
| 	// NOTE: We always need stack optimization when Yul optimizer is disabled. It being disabled
 | ||||
| 	// just means that we don't use the full step sequence. We still run it with the minimal steps
 | ||||
| 	// required to avoid "stack too deep".
 | ||||
| 	bool optimize = m_optimiserSettings.optimizeStackAllocation || !m_optimiserSettings.runYulOptimiser; | ||||
| 	compileEVM(adapter, optimize); | ||||
| 
 | ||||
| 	assembly.optimise(evmasm::Assembly::OptimiserSettings::translateSettings(m_optimiserSettings, m_evmVersion)); | ||||
| 
 | ||||
|  | ||||
| @ -36,8 +36,8 @@ echo '{}' | "$SOLC" - --yul --optimize &>/dev/null && fail "solc --yul --optimiz | ||||
| # Test yul and strict assembly output | ||||
| # Non-empty code results in non-empty binary representation with optimizations turned off, | ||||
| # while it results in empty binary representation with optimizations turned on. | ||||
| test_solc_assembly_output "{ let x:u256 := 0:u256 }" "{ let x := 0 }" "--yul" | ||||
| test_solc_assembly_output "{ let x:u256 := bitnot(7:u256) }" "{ let x := bitnot(7) }" "--yul" | ||||
| test_solc_assembly_output "{ let t:bool := not(true) }" "{ let t:bool := not(true) }" "--yul" | ||||
| test_solc_assembly_output "{ let x := 0 }" "{ let x := 0 }" "--strict-assembly" | ||||
| test_solc_assembly_output "{ let x := 0 }" "{ { } }" "--strict-assembly --optimize" | ||||
| test_solc_assembly_output "{ let x:u256 := 0:u256 mstore(0, x) }" "{ { let x := 0 mstore(0, x) } }" "--yul" | ||||
| test_solc_assembly_output "{ let x:u256 := bitnot(7:u256) mstore(0, x) }" "{ { let x := bitnot(7) mstore(0, x) } }" "--yul" | ||||
| test_solc_assembly_output "{ let t:bool := not(true) if t { mstore(0, 1) } }" "{ { let t:bool := not(true) if t { mstore(0, 1) } } }" "--yul" | ||||
| test_solc_assembly_output "{ let x := 0 mstore(0, x) }" "{ { let x := 0 mstore(0, x) } }" "--strict-assembly" | ||||
| test_solc_assembly_output "{ let x := 0 mstore(0, x) }" "{ { } }" "--strict-assembly --optimize" | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user