mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	Merge pull request #2261 from ethereum/asm-optimizer-rules
Add more assembly optimizer rules
This commit is contained in:
		
						commit
						7e7c00f761
					
				| @ -103,7 +103,7 @@ Rules::Rules() | |||||||
| 		{{Instruction::SMOD, {A, B}}, [=]{ return B.d() == 0 ? 0 : s2u(modWorkaround(u2s(A.d()), u2s(B.d()))); }}, | 		{{Instruction::SMOD, {A, B}}, [=]{ return B.d() == 0 ? 0 : s2u(modWorkaround(u2s(A.d()), u2s(B.d()))); }}, | ||||||
| 		{{Instruction::EXP, {A, B}}, [=]{ return u256(boost::multiprecision::powm(bigint(A.d()), bigint(B.d()), bigint(1) << 256)); }}, | 		{{Instruction::EXP, {A, B}}, [=]{ return u256(boost::multiprecision::powm(bigint(A.d()), bigint(B.d()), bigint(1) << 256)); }}, | ||||||
| 		{{Instruction::NOT, {A}}, [=]{ return ~A.d(); }}, | 		{{Instruction::NOT, {A}}, [=]{ return ~A.d(); }}, | ||||||
| 		{{Instruction::LT, {A, B}}, [=]() { return A.d() < B.d() ? u256(1) : 0; }}, | 		{{Instruction::LT, {A, B}}, [=]() -> u256 { return A.d() < B.d() ? 1 : 0; }}, | ||||||
| 		{{Instruction::GT, {A, B}}, [=]() -> u256 { return A.d() > B.d() ? 1 : 0; }}, | 		{{Instruction::GT, {A, B}}, [=]() -> u256 { return A.d() > B.d() ? 1 : 0; }}, | ||||||
| 		{{Instruction::SLT, {A, B}}, [=]() -> u256 { return u2s(A.d()) < u2s(B.d()) ? 1 : 0; }}, | 		{{Instruction::SLT, {A, B}}, [=]() -> u256 { return u2s(A.d()) < u2s(B.d()) ? 1 : 0; }}, | ||||||
| 		{{Instruction::SGT, {A, B}}, [=]() -> u256 { return u2s(A.d()) > u2s(B.d()) ? 1 : 0; }}, | 		{{Instruction::SGT, {A, B}}, [=]() -> u256 { return u2s(A.d()) > u2s(B.d()) ? 1 : 0; }}, | ||||||
| @ -124,23 +124,26 @@ Rules::Rules() | |||||||
| 			return u256(boost::multiprecision::bit_test(B.d(), testBit) ? B.d() | ~mask : B.d() & mask); | 			return u256(boost::multiprecision::bit_test(B.d(), testBit) ? B.d() | ~mask : B.d() & mask); | ||||||
| 		}}, | 		}}, | ||||||
| 
 | 
 | ||||||
| 		// invariants involving known constants
 | 		// invariants involving known constants (commutative instructions will be checked with swapped operants too)
 | ||||||
| 		{{Instruction::ADD, {X, 0}}, [=]{ return X; }}, | 		{{Instruction::ADD, {X, 0}}, [=]{ return X; }}, | ||||||
| 		{{Instruction::SUB, {X, 0}}, [=]{ return X; }}, | 		{{Instruction::SUB, {X, 0}}, [=]{ return X; }}, | ||||||
| 		{{Instruction::MUL, {X, 1}}, [=]{ return X; }}, |  | ||||||
| 		{{Instruction::DIV, {X, 1}}, [=]{ return X; }}, |  | ||||||
| 		{{Instruction::SDIV, {X, 1}}, [=]{ return X; }}, |  | ||||||
| 		{{Instruction::OR, {X, 0}}, [=]{ return X; }}, |  | ||||||
| 		{{Instruction::XOR, {X, 0}}, [=]{ return X; }}, |  | ||||||
| 		{{Instruction::AND, {X, ~u256(0)}}, [=]{ return X; }}, |  | ||||||
| 		{{Instruction::AND, {X, 0}}, [=]{ return u256(0); }}, |  | ||||||
| 		{{Instruction::MUL, {X, 0}}, [=]{ return u256(0); }}, | 		{{Instruction::MUL, {X, 0}}, [=]{ return u256(0); }}, | ||||||
|  | 		{{Instruction::MUL, {X, 1}}, [=]{ return X; }}, | ||||||
| 		{{Instruction::DIV, {X, 0}}, [=]{ return u256(0); }}, | 		{{Instruction::DIV, {X, 0}}, [=]{ return u256(0); }}, | ||||||
| 		{{Instruction::DIV, {0, X}}, [=]{ return u256(0); }}, | 		{{Instruction::DIV, {0, X}}, [=]{ return u256(0); }}, | ||||||
|  | 		{{Instruction::DIV, {X, 1}}, [=]{ return X; }}, | ||||||
|  | 		{{Instruction::SDIV, {X, 0}}, [=]{ return u256(0); }}, | ||||||
|  | 		{{Instruction::SDIV, {0, X}}, [=]{ return u256(0); }}, | ||||||
|  | 		{{Instruction::SDIV, {X, 1}}, [=]{ return X; }}, | ||||||
|  | 		{{Instruction::AND, {X, ~u256(0)}}, [=]{ return X; }}, | ||||||
|  | 		{{Instruction::AND, {X, 0}}, [=]{ return u256(0); }}, | ||||||
|  | 		{{Instruction::OR, {X, 0}}, [=]{ return X; }}, | ||||||
|  | 		{{Instruction::OR, {X, ~u256(0)}}, [=]{ return ~u256(0); }}, | ||||||
|  | 		{{Instruction::XOR, {X, 0}}, [=]{ return X; }}, | ||||||
| 		{{Instruction::MOD, {X, 0}}, [=]{ return u256(0); }}, | 		{{Instruction::MOD, {X, 0}}, [=]{ return u256(0); }}, | ||||||
| 		{{Instruction::MOD, {0, X}}, [=]{ return u256(0); }}, | 		{{Instruction::MOD, {0, X}}, [=]{ return u256(0); }}, | ||||||
| 		{{Instruction::OR, {X, ~u256(0)}}, [=]{ return ~u256(0); }}, |  | ||||||
| 		{{Instruction::EQ, {X, 0}}, [=]() -> Pattern { return {Instruction::ISZERO, {X}}; } }, | 		{{Instruction::EQ, {X, 0}}, [=]() -> Pattern { return {Instruction::ISZERO, {X}}; } }, | ||||||
|  | 
 | ||||||
| 		// operations involving an expression and itself
 | 		// operations involving an expression and itself
 | ||||||
| 		{{Instruction::AND, {X, X}}, [=]{ return X; }}, | 		{{Instruction::AND, {X, X}}, [=]{ return X; }}, | ||||||
| 		{{Instruction::OR, {X, X}}, [=]{ return X; }}, | 		{{Instruction::OR, {X, X}}, [=]{ return X; }}, | ||||||
| @ -153,6 +156,7 @@ Rules::Rules() | |||||||
| 		{{Instruction::SGT, {X, X}}, [=]{ return u256(0); }}, | 		{{Instruction::SGT, {X, X}}, [=]{ return u256(0); }}, | ||||||
| 		{{Instruction::MOD, {X, X}}, [=]{ return u256(0); }}, | 		{{Instruction::MOD, {X, X}}, [=]{ return u256(0); }}, | ||||||
| 
 | 
 | ||||||
|  | 		// logical instruction combinations
 | ||||||
| 		{{Instruction::NOT, {{Instruction::NOT, {X}}}}, [=]{ return X; }}, | 		{{Instruction::NOT, {{Instruction::NOT, {X}}}}, [=]{ return X; }}, | ||||||
| 		{{Instruction::XOR, {{{X}, {Instruction::XOR, {X, Y}}}}}, [=]{ return Y; }}, | 		{{Instruction::XOR, {{{X}, {Instruction::XOR, {X, Y}}}}}, [=]{ return Y; }}, | ||||||
| 		{{Instruction::OR, {{{X}, {Instruction::AND, {X, Y}}}}}, [=]{ return X; }}, | 		{{Instruction::OR, {{{X}, {Instruction::AND, {X, Y}}}}}, [=]{ return X; }}, | ||||||
| @ -160,6 +164,7 @@ Rules::Rules() | |||||||
| 		{{Instruction::AND, {{{X}, {Instruction::NOT, {X}}}}}, [=]{ return u256(0); }}, | 		{{Instruction::AND, {{{X}, {Instruction::NOT, {X}}}}}, [=]{ return u256(0); }}, | ||||||
| 		{{Instruction::OR, {{{X}, {Instruction::NOT, {X}}}}}, [=]{ return ~u256(0); }}, | 		{{Instruction::OR, {{{X}, {Instruction::NOT, {X}}}}}, [=]{ return ~u256(0); }}, | ||||||
| 	}); | 	}); | ||||||
|  | 
 | ||||||
| 	// Double negation of opcodes with binary result
 | 	// Double negation of opcodes with binary result
 | ||||||
| 	for (auto const& op: vector<Instruction>{ | 	for (auto const& op: vector<Instruction>{ | ||||||
| 		Instruction::EQ, | 		Instruction::EQ, | ||||||
| @ -172,14 +177,17 @@ Rules::Rules() | |||||||
| 			{Instruction::ISZERO, {{Instruction::ISZERO, {{op, {X, Y}}}}}}, | 			{Instruction::ISZERO, {{Instruction::ISZERO, {{op, {X, Y}}}}}}, | ||||||
| 			[=]() -> Pattern { return {op, {X, Y}}; } | 			[=]() -> Pattern { return {op, {X, Y}}; } | ||||||
| 		}); | 		}); | ||||||
|  | 
 | ||||||
| 	addRule({ | 	addRule({ | ||||||
| 		{Instruction::ISZERO, {{Instruction::ISZERO, {{Instruction::ISZERO, {X}}}}}}, | 		{Instruction::ISZERO, {{Instruction::ISZERO, {{Instruction::ISZERO, {X}}}}}}, | ||||||
| 		[=]() -> Pattern { return {Instruction::ISZERO, {X}}; } | 		[=]() -> Pattern { return {Instruction::ISZERO, {X}}; } | ||||||
| 	}); | 	}); | ||||||
|  | 
 | ||||||
| 	addRule({ | 	addRule({ | ||||||
| 		{Instruction::ISZERO, {{Instruction::XOR, {X, Y}}}}, | 		{Instruction::ISZERO, {{Instruction::XOR, {X, Y}}}}, | ||||||
| 		[=]() -> Pattern { return { Instruction::EQ, {X, Y} }; } | 		[=]() -> Pattern { return { Instruction::EQ, {X, Y} }; } | ||||||
| 	}); | 	}); | ||||||
|  | 
 | ||||||
| 	// Associative operations
 | 	// Associative operations
 | ||||||
| 	for (auto const& opFun: vector<pair<Instruction,function<u256(u256 const&,u256 const&)>>>{ | 	for (auto const& opFun: vector<pair<Instruction,function<u256(u256 const&,u256 const&)>>>{ | ||||||
| 		{Instruction::ADD, plus<u256>()}, | 		{Instruction::ADD, plus<u256>()}, | ||||||
| @ -210,6 +218,7 @@ Rules::Rules() | |||||||
| 			[=]() -> Pattern { return {op, {{op, {X, Y}}, A}}; } | 			[=]() -> Pattern { return {op, {{op, {X, Y}}, A}}; } | ||||||
| 		}}); | 		}}); | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
| 	// move constants across subtractions
 | 	// move constants across subtractions
 | ||||||
| 	addRules(vector<pair<Pattern, function<Pattern()>>>{ | 	addRules(vector<pair<Pattern, function<Pattern()>>>{ | ||||||
| 		{ | 		{ | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user