mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	Merge pull request #6968 from ethereum/completeWordSizeTransform
[Yul] More work on word size transform
This commit is contained in:
		
						commit
						dcb430c09f
					
				| @ -18,6 +18,8 @@ | ||||
| #include <libyul/AsmData.h> | ||||
| #include <libyul/backends/wasm/WordSizeTransform.h> | ||||
| #include <libyul/Utilities.h> | ||||
| #include <libyul/Dialect.h> | ||||
| #include <libyul/optimiser/NameDisplacer.h> | ||||
| 
 | ||||
| #include <libdevcore/CommonData.h> | ||||
| 
 | ||||
| @ -41,6 +43,10 @@ void WordSizeTransform::operator()(FunctionalInstruction& _ins) | ||||
| 
 | ||||
| void WordSizeTransform::operator()(FunctionCall& _fc) | ||||
| { | ||||
| 	if (BuiltinFunction const* fun = m_inputDialect.builtin(_fc.functionName.name)) | ||||
| 		if (fun->literalArguments) | ||||
| 			return; | ||||
| 
 | ||||
| 	rewriteFunctionCallArguments(_fc.arguments); | ||||
| } | ||||
| 
 | ||||
| @ -48,7 +54,7 @@ void WordSizeTransform::operator()(If& _if) | ||||
| { | ||||
| 	_if.condition = make_unique<Expression>(FunctionCall{ | ||||
| 		locationOf(*_if.condition), | ||||
| 		Identifier{locationOf(*_if.condition), "or_bool"_yulstring}, // TODO make sure this is not used
 | ||||
| 		Identifier{locationOf(*_if.condition), "or_bool"_yulstring}, | ||||
| 		expandValueToVector(*_if.condition) | ||||
| 	}); | ||||
| 	(*this)(_if.body); | ||||
| @ -59,6 +65,18 @@ void WordSizeTransform::operator()(Switch&) | ||||
| 	yulAssert(false, "Switch statement not implemented."); | ||||
| } | ||||
| 
 | ||||
| void WordSizeTransform::operator()(ForLoop& _for) | ||||
| { | ||||
| 	(*this)(_for.pre); | ||||
| 	_for.condition = make_unique<Expression>(FunctionCall{ | ||||
| 		locationOf(*_for.condition), | ||||
| 		Identifier{locationOf(*_for.condition), "or_bool"_yulstring}, | ||||
| 		expandValueToVector(*_for.condition) | ||||
| 	}); | ||||
| 	(*this)(_for.post); | ||||
| 	(*this)(_for.body); | ||||
| } | ||||
| 
 | ||||
| void WordSizeTransform::operator()(Block& _block) | ||||
| { | ||||
| 	iterateReplacing( | ||||
| @ -142,9 +160,11 @@ void WordSizeTransform::operator()(Block& _block) | ||||
| 	); | ||||
| } | ||||
| 
 | ||||
| void WordSizeTransform::run(Block& _ast, NameDispenser& _nameDispenser) | ||||
| void WordSizeTransform::run(Dialect const& _inputDialect, Block& _ast, NameDispenser& _nameDispenser) | ||||
| { | ||||
| 	WordSizeTransform{_nameDispenser}(_ast); | ||||
| 	// Free the name `or_bool`.
 | ||||
| 	NameDisplacer{_nameDispenser, {"or_bool"_yulstring}}(_ast); | ||||
| 	WordSizeTransform{_inputDialect, _nameDispenser}(_ast); | ||||
| } | ||||
| 
 | ||||
| void WordSizeTransform::rewriteVarDeclList(TypedNameList& _nameList) | ||||
|  | ||||
| @ -51,7 +51,7 @@ namespace yul | ||||
|  * take four times the parameters and each of type u64. | ||||
|  * In addition, it uses a single other builtin function called `or_bool` that | ||||
|  * takes four u64 parameters and is supposed to return the logical disjunction | ||||
|  * of them es a u64 value. | ||||
|  * of them as a u64 value. If this name is already used somewhere, it is renamed. | ||||
|  * | ||||
|  * Prerequisite: Disambiguator, ExpressionSplitter | ||||
|  */ | ||||
| @ -63,12 +63,14 @@ public: | ||||
| 	void operator()(FunctionCall&) override; | ||||
| 	void operator()(If&) override; | ||||
| 	void operator()(Switch&) override; | ||||
| 	void operator()(ForLoop&) override; | ||||
| 	void operator()(Block& _block) override; | ||||
| 
 | ||||
| 	static void run(Block& _ast, NameDispenser& _nameDispenser); | ||||
| 	static void run(Dialect const& _inputDialect, Block& _ast, NameDispenser& _nameDispenser); | ||||
| 
 | ||||
| private: | ||||
| 	explicit WordSizeTransform(NameDispenser& _nameDispenser): | ||||
| 	explicit WordSizeTransform(Dialect const& _inputDialect, NameDispenser& _nameDispenser): | ||||
| 		m_inputDialect(_inputDialect), | ||||
| 		m_nameDispenser(_nameDispenser) | ||||
| 	{ } | ||||
| 
 | ||||
| @ -80,6 +82,7 @@ private: | ||||
| 	std::array<std::unique_ptr<Expression>, 4> expandValue(Expression const& _e); | ||||
| 	std::vector<Expression> expandValueToVector(Expression const& _e); | ||||
| 
 | ||||
| 	Dialect const& m_inputDialect; | ||||
| 	NameDispenser& m_nameDispenser; | ||||
| 	/// maps original u256 variable's name to corresponding u64 variables' names
 | ||||
| 	std::map<YulString, std::array<YulString, 4>> m_variableMapping; | ||||
|  | ||||
| @ -297,7 +297,7 @@ TestCase::TestResult YulOptimizerTest::run(ostream& _stream, string const& _line | ||||
| 		disambiguate(); | ||||
| 		NameDispenser nameDispenser{*m_dialect, *m_ast}; | ||||
| 		ExpressionSplitter{*m_dialect, nameDispenser}(*m_ast); | ||||
| 		WordSizeTransform::run(*m_ast, nameDispenser); | ||||
| 		WordSizeTransform::run(*m_dialect, *m_ast, nameDispenser); | ||||
| 	} | ||||
| 	else if (m_optimizerStep == "fullSuite") | ||||
| 	{ | ||||
|  | ||||
| @ -0,0 +1,25 @@ | ||||
| { | ||||
|     let or_bool := 2 | ||||
|     if or_bool { sstore(0, 1) } | ||||
| } | ||||
| // ==== | ||||
| // step: wordSizeTransform | ||||
| // ---- | ||||
| // { | ||||
| //     let or_bool_3_0 := 0 | ||||
| //     let or_bool_3_1 := 0 | ||||
| //     let or_bool_3_2 := 0 | ||||
| //     let or_bool_3_3 := 2 | ||||
| //     if or_bool(or_bool_3_0, or_bool_3_1, or_bool_3_2, or_bool_3_3) | ||||
| //     { | ||||
| //         let _1_0 := 0 | ||||
| //         let _1_1 := 0 | ||||
| //         let _1_2 := 0 | ||||
| //         let _1_3 := 1 | ||||
| //         let _2_0 := 0 | ||||
| //         let _2_1 := 0 | ||||
| //         let _2_2 := 0 | ||||
| //         let _2_3 := 0 | ||||
| //         sstore(_2_0, _2_1, _2_2, _2_3, _1_0, _1_1, _1_2, _1_3) | ||||
| //     } | ||||
| // } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user