mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	Run yul optimizer on user code without refs
This commit is contained in:
		
							parent
							
								
									3a4cb016ff
								
							
						
					
					
						commit
						1a3998648c
					
				| @ -20,6 +20,8 @@ | ||||
|  * Solidity compiler. | ||||
|  */ | ||||
| 
 | ||||
| 
 | ||||
| #include <functional> | ||||
| #include <libsolidity/ast/AST.h> | ||||
| #include <libsolidity/ast/ASTUtils.h> | ||||
| #include <libsolidity/ast/TypeProvider.h> | ||||
| @ -27,7 +29,16 @@ | ||||
| #include <libsolidity/codegen/ContractCompiler.h> | ||||
| #include <libsolidity/codegen/ExpressionCompiler.h> | ||||
| 
 | ||||
| #include <libyul/AsmAnalysisInfo.h> | ||||
| #include <libyul/AsmData.h> | ||||
| #include <libyul/AsmDataForward.h> | ||||
| #include <libyul/backends/evm/AsmCodeGen.h> | ||||
| #include <libyul/backends/evm/EVMMetrics.h> | ||||
| #include <libyul/backends/evm/EVMDialect.h> | ||||
| #include <libyul/optimiser/Suite.h> | ||||
| #include <libyul/Object.h> | ||||
| #include <libyul/optimiser/ASTCopier.h> | ||||
| #include <libyul/YulString.h> | ||||
| 
 | ||||
| #include <libevmasm/Instruction.h> | ||||
| #include <libevmasm/Assembly.h> | ||||
| @ -40,6 +51,13 @@ | ||||
| #include <boost/range/adaptor/reversed.hpp> | ||||
| #include <algorithm> | ||||
| 
 | ||||
| 
 | ||||
| // Change to "define" to output all intermediate code
 | ||||
| #undef SOL_OUTPUT_ASM | ||||
| #ifdef SOL_OUTPUT_ASM | ||||
| #include <libyul/AsmPrinter.h> | ||||
| #endif | ||||
| 
 | ||||
| using namespace std; | ||||
| using namespace solidity; | ||||
| using namespace solidity::evmasm; | ||||
| @ -788,10 +806,65 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly) | ||||
| 			_assembly.appendInstruction(Instruction::POP); | ||||
| 		} | ||||
| 	}; | ||||
| 	solAssert(_inlineAssembly.annotation().analysisInfo, ""); | ||||
| 
 | ||||
| 	yul::Block const* code = &_inlineAssembly.operations(); | ||||
| 	yul::AsmAnalysisInfo* analysisInfo = _inlineAssembly.annotation().analysisInfo.get(); | ||||
| 
 | ||||
| 	// Only used in the scope below, but required to live outside to keep the
 | ||||
| 	// shared_ptr's alive
 | ||||
| 	yul::Object object; | ||||
| 
 | ||||
| 	// The optimiser cannot handle external references
 | ||||
| 	if ( | ||||
| 		m_optimiserSettings.runYulOptimiser && | ||||
| 		_inlineAssembly.annotation().externalReferences.empty() | ||||
| 	) | ||||
| 	{ | ||||
| 		// Create a modifiable copy of the code and analysis
 | ||||
| 		object.code = make_shared<yul::Block>(yul::ASTCopier().translate(*code)); | ||||
| 		object.analysisInfo = make_shared<yul::AsmAnalysisInfo>(); | ||||
| 
 | ||||
| 		{ | ||||
| 			ErrorList errList; | ||||
| 			ErrorReporter errorReporter{errList}; | ||||
| 
 | ||||
| 			yul::AsmAnalyzer analyzer( | ||||
| 				*object.analysisInfo, | ||||
| 				errorReporter, | ||||
| 				_inlineAssembly.dialect() | ||||
| 			); | ||||
| 			solAssert(analyzer.analyze(*object.code), "Inline analysis failed."); | ||||
| 		} | ||||
| 
 | ||||
| 		yul::EVMDialect const* dialect = dynamic_cast<decltype(dialect)>(&_inlineAssembly.dialect()); | ||||
| 		solAssert(dialect, ""); | ||||
| 
 | ||||
| #ifdef SOL_OUTPUT_ASM | ||||
| 		cout << yul::AsmPrinter(*dialect)(*object.code) << endl; | ||||
| #endif | ||||
| 
 | ||||
| 		bool const isCreation = m_context.runtimeContext() != nullptr; | ||||
| 		yul::GasMeter meter(*dialect, isCreation, m_optimiserSettings.expectedExecutionsPerDeployment); | ||||
| 		yul::OptimiserSuite::run( | ||||
| 			*dialect, | ||||
| 			&meter, | ||||
| 			object, | ||||
| 			m_optimiserSettings.optimizeStackAllocation, | ||||
| 			{} | ||||
| 		); | ||||
| 
 | ||||
| #ifdef SOL_OUTPUT_ASM | ||||
| 		cout << "After optimizer:" << endl; | ||||
| 		cout << yul::AsmPrinter(*dialect)(*object.code) << endl; | ||||
| #endif | ||||
| 		code = object.code.get(); | ||||
| 		analysisInfo = object.analysisInfo.get(); | ||||
| 	} | ||||
| 
 | ||||
| 	solAssert(analysisInfo, ""); | ||||
| 	yul::CodeGenerator::assemble( | ||||
| 		_inlineAssembly.operations(), | ||||
| 		*_inlineAssembly.annotation().analysisInfo, | ||||
| 		*code, | ||||
| 		*analysisInfo, | ||||
| 		*m_context.assemblyPtr(), | ||||
| 		m_context.evmVersion(), | ||||
| 		identifierAccess, | ||||
|  | ||||
| @ -84,6 +84,7 @@ public: | ||||
| 	virtual Expression translate(Expression const& _expression); | ||||
| 	virtual Statement translate(Statement const& _statement); | ||||
| 
 | ||||
| 	Block translate(Block const& _block); | ||||
| protected: | ||||
| 	template <typename T> | ||||
| 	std::vector<T> translateVector(std::vector<T> const& _values); | ||||
| @ -94,7 +95,6 @@ protected: | ||||
| 		return _v ? std::make_unique<T>(translate(*_v)) : nullptr; | ||||
| 	} | ||||
| 
 | ||||
| 	Block translate(Block const& _block); | ||||
| 	Case translate(Case const& _case); | ||||
| 	virtual Identifier translate(Identifier const& _identifier); | ||||
| 	Literal translate(Literal const& _literal); | ||||
|  | ||||
							
								
								
									
										1
									
								
								test/cmdlineTests/optimizer_user_yul/args
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								test/cmdlineTests/optimizer_user_yul/args
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | ||||
| --optimize --asm --metadata-hash none | ||||
							
								
								
									
										37
									
								
								test/cmdlineTests/optimizer_user_yul/input.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								test/cmdlineTests/optimizer_user_yul/input.sol
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | ||||
| pragma solidity >=0.0; | ||||
| 
 | ||||
| contract C | ||||
| { | ||||
| 	constructor() public payable | ||||
| 	{ | ||||
| 		int a; | ||||
| 
 | ||||
| 		// Can't be optimized due to external reference "a" | ||||
| 		assembly | ||||
| 		{ | ||||
| 			let x,y,z | ||||
| 
 | ||||
| 			sstore(0, 1) | ||||
| 
 | ||||
| 			for { } sload(4) { } { | ||||
| 				z := exp(x, y) | ||||
| 			} | ||||
| 
 | ||||
| 			a := 2 | ||||
| 		} | ||||
| 
 | ||||
| 		// Can be optimized due to no external references | ||||
| 		assembly | ||||
| 		{ | ||||
| 			let x,y,z | ||||
| 
 | ||||
| 			sstore(2, 3) | ||||
| 
 | ||||
| 			for { } sload(5) { } { | ||||
| 				// Expected to be optimized out for yulOptimizer, but not for | ||||
| 				// old optimizer | ||||
| 				z := exp(x, y) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										87
									
								
								test/cmdlineTests/optimizer_user_yul/output
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								test/cmdlineTests/optimizer_user_yul/output
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,87 @@ | ||||
| 
 | ||||
| ======= optimizer_user_yul/input.sol:C ======= | ||||
| EVM assembly: | ||||
|     /* "optimizer_user_yul/input.sol":24:489  contract C... */ | ||||
|   mstore(0x40, 0x80) | ||||
|     /* "optimizer_user_yul/input.sol":72:77  int a */ | ||||
|   0x00 | ||||
|     /* "optimizer_user_yul/input.sol":38:487  constructor() public payable... */ | ||||
|   dup1 | ||||
|   0x00 | ||||
|   dup1 | ||||
|     /* "optimizer_user_yul/input.sol":176:177  1 */ | ||||
|   0x01 | ||||
|     /* "optimizer_user_yul/input.sol":173:174  0 */ | ||||
|   0x00 | ||||
|     /* "optimizer_user_yul/input.sol":166:178  sstore(0, 1) */ | ||||
|   sstore | ||||
|     /* "optimizer_user_yul/input.sol":183:229  for { } sload(4) { } {... */ | ||||
| tag_3: | ||||
|     /* "optimizer_user_yul/input.sol":197:198  4 */ | ||||
|   0x04 | ||||
|     /* "optimizer_user_yul/input.sol":191:199  sload(4) */ | ||||
|   sload | ||||
|     /* "optimizer_user_yul/input.sol":183:229  for { } sload(4) { } {... */ | ||||
|   iszero | ||||
|   tag_5 | ||||
|   jumpi | ||||
|   pop | ||||
|     /* "optimizer_user_yul/input.sol":215:224  exp(x, y) */ | ||||
|   dup1 | ||||
|   dup3 | ||||
|   exp | ||||
|     /* "optimizer_user_yul/input.sol":183:229  for { } sload(4) { } {... */ | ||||
|   jump(tag_3) | ||||
| tag_5: | ||||
|     /* "optimizer_user_yul/input.sol":187:190  { } */ | ||||
|   pop | ||||
|   pop | ||||
|   pop | ||||
|     /* "optimizer_user_yul/input.sol":239:240  2 */ | ||||
|   0x02 | ||||
|     /* "optimizer_user_yul/input.sol":234:240  a := 2 */ | ||||
|   swap1 | ||||
|   pop | ||||
|     /* "optimizer_user_yul/input.sol":340:341  3 */ | ||||
|   0x03 | ||||
|     /* "optimizer_user_yul/input.sol":337:338  2 */ | ||||
|   0x02 | ||||
|     /* "optimizer_user_yul/input.sol":330:342  sstore(2, 3) */ | ||||
|   sstore | ||||
|     /* "optimizer_user_yul/input.sol":347:480  for { } sload(5) { } {... */ | ||||
| tag_6: | ||||
|     /* "optimizer_user_yul/input.sol":361:362  5 */ | ||||
|   0x05 | ||||
|     /* "optimizer_user_yul/input.sol":355:363  sload(5) */ | ||||
|   sload | ||||
|   tag_9 | ||||
|   jumpi | ||||
|   jump(tag_8) | ||||
| tag_9: | ||||
|     /* "optimizer_user_yul/input.sol":347:480  for { } sload(5) { } {... */ | ||||
|   jump(tag_6) | ||||
| tag_8: | ||||
|     /* "optimizer_user_yul/input.sol":311:484  {... */ | ||||
|   pop | ||||
|     /* "optimizer_user_yul/input.sol":24:489  contract C... */ | ||||
|   dataSize(sub_0) | ||||
|   dup1 | ||||
|   dataOffset(sub_0) | ||||
|   0x00 | ||||
|   codecopy | ||||
|   0x00 | ||||
|   return | ||||
| stop | ||||
| 
 | ||||
| sub_0: assembly { | ||||
|         /* "optimizer_user_yul/input.sol":24:489  contract C... */ | ||||
|       mstore(0x40, 0x80) | ||||
|         /* "--CODEGEN--":12:13   */ | ||||
|       0x00 | ||||
|         /* "--CODEGEN--":9:10   */ | ||||
|       dup1 | ||||
|         /* "--CODEGEN--":2:14   */ | ||||
|       revert | ||||
| 
 | ||||
|     auxdata: 0xa164736f6c63782a302e362e332d646576656c6f702e323032302e322e362b636f6d6d69742e31353237396436392e6d6f640032 | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user