mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	Adding ssa type check and test for that one
This commit is contained in:
		
							parent
							
								
									2efda4129b
								
							
						
					
					
						commit
						c891597204
					
				| @ -27,6 +27,8 @@ | ||||
| 
 | ||||
| #include <libsolutil/CommonData.h> | ||||
| 
 | ||||
| #include <libyul/optimiser/TypeInfo.h> | ||||
| 
 | ||||
| using namespace std; | ||||
| using namespace solidity; | ||||
| using namespace solidity::yul; | ||||
| @ -42,8 +44,14 @@ namespace | ||||
| class IntroduceSSA: public ASTModifier | ||||
| { | ||||
| public: | ||||
| 	explicit IntroduceSSA(NameDispenser& _nameDispenser, set<YulString> const& _variablesToReplace): | ||||
| 		m_nameDispenser(_nameDispenser), m_variablesToReplace(_variablesToReplace) | ||||
| 	explicit IntroduceSSA( | ||||
| 		NameDispenser& _nameDispenser, | ||||
| 		set<YulString> const& _variablesToReplace, | ||||
| 		TypeInfo& _typeInfo | ||||
| 	): | ||||
| 		m_nameDispenser(_nameDispenser), | ||||
| 		m_variablesToReplace(_variablesToReplace), | ||||
| 		m_typeInfo(_typeInfo) | ||||
| 	{ } | ||||
| 
 | ||||
| 	void operator()(Block& _block) override; | ||||
| @ -51,6 +59,7 @@ public: | ||||
| private: | ||||
| 	NameDispenser& m_nameDispenser; | ||||
| 	set<YulString> const& m_variablesToReplace; | ||||
| 	TypeInfo const& m_typeInfo; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| @ -83,10 +92,10 @@ void IntroduceSSA::operator()(Block& _block) | ||||
| 				{ | ||||
| 					YulString oldName = var.name; | ||||
| 					YulString newName = m_nameDispenser.newName(oldName); | ||||
| 					newVariables.emplace_back(TypedName{loc, newName, {}}); | ||||
| 					newVariables.emplace_back(TypedName{loc, newName, var.type}); | ||||
| 					statements.emplace_back(VariableDeclaration{ | ||||
| 						loc, | ||||
| 						{TypedName{loc, oldName, {}}}, | ||||
| 						{TypedName{loc, oldName, var.type}}, | ||||
| 						make_unique<Expression>(Identifier{loc, newName}) | ||||
| 					}); | ||||
| 				} | ||||
| @ -110,7 +119,11 @@ void IntroduceSSA::operator()(Block& _block) | ||||
| 				{ | ||||
| 					YulString oldName = var.name; | ||||
| 					YulString newName = m_nameDispenser.newName(oldName); | ||||
| 					newVariables.emplace_back(TypedName{loc, newName, {}}); | ||||
| 					newVariables.emplace_back(TypedName{ | ||||
| 						loc, | ||||
| 						newName, | ||||
| 						m_typeInfo.typeOfVariable(oldName) | ||||
| 					}); | ||||
| 					statements.emplace_back(Assignment{ | ||||
| 						loc, | ||||
| 						{Identifier{loc, oldName}}, | ||||
| @ -136,9 +149,12 @@ class IntroduceControlFlowSSA: public ASTModifier | ||||
| public: | ||||
| 	explicit IntroduceControlFlowSSA( | ||||
| 		NameDispenser& _nameDispenser, | ||||
| 		set<YulString> const& _variablesToReplace | ||||
| 		set<YulString> const& _variablesToReplace, | ||||
| 		TypeInfo const& _typeInfo | ||||
| 	): | ||||
| 		m_nameDispenser(_nameDispenser), m_variablesToReplace(_variablesToReplace) | ||||
| 		m_nameDispenser(_nameDispenser), | ||||
| 		m_variablesToReplace(_variablesToReplace), | ||||
| 		m_typeInfo(_typeInfo) | ||||
| 	{ } | ||||
| 
 | ||||
| 	void operator()(FunctionDefinition& _function) override; | ||||
| @ -153,6 +169,7 @@ private: | ||||
| 	set<YulString> m_variablesInScope; | ||||
| 	/// Set of variables that do not have a specific value.
 | ||||
| 	set<YulString> m_variablesToReassign; | ||||
| 	TypeInfo const& m_typeInfo; | ||||
| }; | ||||
| 
 | ||||
| void IntroduceControlFlowSSA::operator()(FunctionDefinition& _function) | ||||
| @ -221,7 +238,7 @@ void IntroduceControlFlowSSA::operator()(Block& _block) | ||||
| 				YulString newName = m_nameDispenser.newName(toReassign); | ||||
| 				toPrepend.emplace_back(VariableDeclaration{ | ||||
| 					locationOf(_s), | ||||
| 					{TypedName{locationOf(_s), newName, {}}}, | ||||
| 					{TypedName{locationOf(_s), newName, m_typeInfo.typeOfVariable(toReassign)}}, | ||||
| 					make_unique<Expression>(Identifier{locationOf(_s), toReassign}) | ||||
| 				}); | ||||
| 				assignedVariables.insert(toReassign); | ||||
| @ -375,10 +392,11 @@ void PropagateValues::operator()(Block& _block) | ||||
| 
 | ||||
| void SSATransform::run(OptimiserStepContext& _context, Block& _ast) | ||||
| { | ||||
| 	TypeInfo typeInfo(_context.dialect, _ast); | ||||
| 	Assignments assignments; | ||||
| 	assignments(_ast); | ||||
| 	IntroduceSSA{_context.dispenser, assignments.names()}(_ast); | ||||
| 	IntroduceControlFlowSSA{_context.dispenser, assignments.names()}(_ast); | ||||
| 	IntroduceSSA{_context.dispenser, assignments.names(), typeInfo}(_ast); | ||||
| 	IntroduceControlFlowSSA{_context.dispenser, assignments.names(), typeInfo}(_ast); | ||||
| 	PropagateValues{assignments.names()}(_ast); | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -96,3 +96,8 @@ YulString TypeInfo::typeOf(Expression const& _expression) const | ||||
| 		} | ||||
| 	}, _expression); | ||||
| } | ||||
| 
 | ||||
| YulString TypeInfo::typeOfVariable(YulString _name) const | ||||
| { | ||||
| 	return m_variableTypes.at(_name); | ||||
| } | ||||
|  | ||||
| @ -44,6 +44,9 @@ public: | ||||
| 	/// @returns the type of an expression that is assumed to return exactly one value.
 | ||||
| 	YulString typeOf(Expression const& _expression) const; | ||||
| 
 | ||||
| 	/// \returns the type of variable
 | ||||
| 	YulString typeOfVariable(YulString _name) const; | ||||
| 
 | ||||
| private: | ||||
| 	class TypeCollector; | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										41
									
								
								test/libyul/yulOptimizerTests/ssaTransform/typed.yul
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								test/libyul/yulOptimizerTests/ssaTransform/typed.yul
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,41 @@ | ||||
| { | ||||
|   let b:bool := true | ||||
|   let c:bool := false | ||||
|   c := b | ||||
|   b := false | ||||
| 
 | ||||
|   let a:u256 := 1 | ||||
|   a := add(a, 1) | ||||
|   if c { | ||||
|     a := add(a, 1) | ||||
|   } | ||||
|   a := add(a, 1) | ||||
|   mstore(a, 1) | ||||
| } | ||||
| // ==== | ||||
| // dialect: evmTyped | ||||
| // step: ssaTransform | ||||
| // ---- | ||||
| // { | ||||
| //     let b_1:bool := true | ||||
| //     let b:bool := b_1 | ||||
| //     let c_2:bool := false | ||||
| //     let c:bool := c_2 | ||||
| //     let c_3:bool := b_1 | ||||
| //     c := c_3 | ||||
| //     let b_4:bool := false | ||||
| //     b := b_4 | ||||
| //     let a_5 := 1 | ||||
| //     let a := a_5 | ||||
| //     let a_6 := add(a_5, 1) | ||||
| //     a := a_6 | ||||
| //     if c_3 | ||||
| //     { | ||||
| //         let a_7 := add(a_6, 1) | ||||
| //         a := a_7 | ||||
| //     } | ||||
| //     let a_9 := a | ||||
| //     let a_8 := add(a_9, 1) | ||||
| //     a := a_8 | ||||
| //     mstore(a_8, 1) | ||||
| // } | ||||
							
								
								
									
										25
									
								
								test/libyul/yulOptimizerTests/ssaTransform/typed_for.yul
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								test/libyul/yulOptimizerTests/ssaTransform/typed_for.yul
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | ||||
| { | ||||
|   let b:bool := true | ||||
|   let c:bool := false | ||||
|   for {} b {} { | ||||
|       c := true | ||||
|   } | ||||
|   let d: bool := c | ||||
| } | ||||
| // ==== | ||||
| // dialect: evmTyped | ||||
| // step: ssaTransform | ||||
| // ---- | ||||
| // { | ||||
| //     let b:bool := true | ||||
| //     let c_1:bool := false | ||||
| //     let c:bool := c_1 | ||||
| //     for { } b { } | ||||
| //     { | ||||
| //         let c_3:bool := c | ||||
| //         let c_2:bool := true | ||||
| //         c := c_2 | ||||
| //     } | ||||
| //     let c_4:bool := c | ||||
| //     let d:bool := c_4 | ||||
| // } | ||||
							
								
								
									
										25
									
								
								test/libyul/yulOptimizerTests/ssaTransform/typed_switch.yul
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								test/libyul/yulOptimizerTests/ssaTransform/typed_switch.yul
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | ||||
| { | ||||
|   let b:bool := true | ||||
|   let c:bool := false | ||||
|   switch b | ||||
|   case true { c := true} | ||||
|   case false { } | ||||
|   let d: bool := c | ||||
| } | ||||
| // ==== | ||||
| // dialect: evmTyped | ||||
| // step: ssaTransform | ||||
| // ---- | ||||
| // { | ||||
| //     let b:bool := true | ||||
| //     let c_1:bool := false | ||||
| //     let c:bool := c_1 | ||||
| //     switch b | ||||
| //     case true { | ||||
| //         let c_2:bool := true | ||||
| //         c := c_2 | ||||
| //     } | ||||
| //     case false { } | ||||
| //     let c_3:bool := c | ||||
| //     let d:bool := c_3 | ||||
| // } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user