yul: Add new optimizer rules for create and create2 builtins

This commit is contained in:
Bhargava Shastry 2019-09-09 13:37:25 +02:00
parent 96b6b45658
commit 09fa31ccc5
5 changed files with 92 additions and 19 deletions

View File

@ -271,9 +271,7 @@ std::vector<SimplificationRule<Pattern>> simplificationRuleListPart5(
Instruction::ADDRESS,
Instruction::CALLER,
Instruction::ORIGIN,
Instruction::COINBASE,
Instruction::CREATE,
Instruction::CREATE2
Instruction::COINBASE
})
{
u256 const mask = (u256(1) << 160) - 1;
@ -288,6 +286,7 @@ std::vector<SimplificationRule<Pattern>> simplificationRuleListPart5(
false
});
}
return rules;
}
@ -565,8 +564,48 @@ std::vector<SimplificationRule<Pattern>> simplificationRuleListPart8(
return rules;
}
template <class Pattern>
std::vector<SimplificationRule<Pattern>> simplificationRuleListPart9(
Pattern,
Pattern,
Pattern,
Pattern W,
Pattern X,
Pattern Y,
Pattern Z
)
{
std::vector<SimplificationRule<Pattern>> rules;
u256 const mask = (u256(1) << 160) - 1;
// CREATE
rules.push_back({
{Instruction::AND, {{Instruction::CREATE, {W, X, Y}}, mask}},
[=]() -> Pattern { return {Instruction::CREATE, {W, X, Y}}; },
false
});
rules.push_back({
{Instruction::AND, {{mask, {Instruction::CREATE, {W, X, Y}}}}},
[=]() -> Pattern { return {Instruction::CREATE, {W, X, Y}}; },
false
});
// CREATE2
rules.push_back({
{Instruction::AND, {{Instruction::CREATE2, {W, X, Y, Z}}, mask}},
[=]() -> Pattern { return {Instruction::CREATE2, {W, X, Y, Z}}; },
false
});
rules.push_back({
{Instruction::AND, {{mask, {Instruction::CREATE2, {W, X, Y, Z}}}}},
[=]() -> Pattern { return {Instruction::CREATE2, {W, X, Y, Z}}; },
false
});
return rules;
}
/// @returns a list of simplification rules given certain match placeholders.
/// A, B and C should represent constants, X and Y arbitrary expressions.
/// A, B and C should represent constants, W, X, Y, and Z arbitrary expressions.
/// The simplifications should never change the order of evaluation of
/// arbitrary operations.
template <class Pattern>
@ -574,19 +613,22 @@ std::vector<SimplificationRule<Pattern>> simplificationRuleList(
Pattern A,
Pattern B,
Pattern C,
Pattern W,
Pattern X,
Pattern Y
Pattern Y,
Pattern Z
)
{
std::vector<SimplificationRule<Pattern>> rules;
rules += simplificationRuleListPart1(A, B, C, X, Y);
rules += simplificationRuleListPart2(A, B, C, X, Y);
rules += simplificationRuleListPart3(A, B, C, X, Y);
rules += simplificationRuleListPart4(A, B, C, X, Y);
rules += simplificationRuleListPart5(A, B, C, X, Y);
rules += simplificationRuleListPart6(A, B, C, X, Y);
rules += simplificationRuleListPart7(A, B, C, X, Y);
rules += simplificationRuleListPart8(A, B, C, X, Y);
rules += simplificationRuleListPart1(A, B, C, W, X);
rules += simplificationRuleListPart2(A, B, C, W, X);
rules += simplificationRuleListPart3(A, B, C, W, X);
rules += simplificationRuleListPart4(A, B, C, W, X);
rules += simplificationRuleListPart5(A, B, C, W, X);
rules += simplificationRuleListPart6(A, B, C, W, X);
rules += simplificationRuleListPart7(A, B, C, W, X);
rules += simplificationRuleListPart8(A, B, C, W, X);
rules += simplificationRuleListPart9(A, B, C, W, X, Y, Z);
return rules;
}

View File

@ -83,15 +83,19 @@ Rules::Rules()
Pattern B(Push);
Pattern C(Push);
// Anything.
Pattern W;
Pattern X;
Pattern Y;
Pattern Z;
A.setMatchGroup(1, m_matchGroups);
B.setMatchGroup(2, m_matchGroups);
C.setMatchGroup(3, m_matchGroups);
X.setMatchGroup(4, m_matchGroups);
Y.setMatchGroup(5, m_matchGroups);
W.setMatchGroup(4, m_matchGroups);
X.setMatchGroup(5, m_matchGroups);
Y.setMatchGroup(6, m_matchGroups);
Z.setMatchGroup(7, m_matchGroups);
addRules(simplificationRuleList(A, B, C, X, Y));
addRules(simplificationRuleList(A, B, C, W, X, Y, Z));
assertThrow(isInitialized(), OptimizerException, "Rule list not properly initialized.");
}

View File

@ -97,15 +97,19 @@ SimplificationRules::SimplificationRules()
Pattern B(PatternKind::Constant);
Pattern C(PatternKind::Constant);
// Anything.
Pattern W;
Pattern X;
Pattern Y;
Pattern Z;
A.setMatchGroup(1, m_matchGroups);
B.setMatchGroup(2, m_matchGroups);
C.setMatchGroup(3, m_matchGroups);
X.setMatchGroup(4, m_matchGroups);
Y.setMatchGroup(5, m_matchGroups);
W.setMatchGroup(4, m_matchGroups);
X.setMatchGroup(5, m_matchGroups);
Y.setMatchGroup(6, m_matchGroups);
Z.setMatchGroup(7, m_matchGroups);
addRules(simplificationRuleList(A, B, C, X, Y));
addRules(simplificationRuleList(A, B, C, W, X, Y, Z));
assertThrow(isInitialized(), OptimizerException, "Rule list not properly initialized.");
}

View File

@ -0,0 +1,12 @@
{
let a := and(create2(0, 0, 0x20, 0), 0xffffffffffffffffffffffffffffffffffffffff)
let b := and(0xffffffffffffffffffffffffffffffffffffffff, create2(0, 0, 0x20, 0))
}
// ====
// step: expressionSimplifier
// EVMVersion: >=constantinople
// ----
// {
// let a := create2(0, 0, 0x20, 0)
// let b := create2(0, 0, 0x20, 0)
// }

View File

@ -0,0 +1,11 @@
{
let a := and(create(0, 0, 0x20), 0xffffffffffffffffffffffffffffffffffffffff)
let b := and(0xffffffffffffffffffffffffffffffffffffffff, create(0, 0, 0x20))
}
// ====
// step: expressionSimplifier
// ----
// {
// let a := create(0, 0, 0x20)
// let b := create(0, 0, 0x20)
// }