[yul] Add support for EVM version-dependent rules.#8958
Conversation
6c87973 to
99768c2
Compare
This comment has been minimized.
This comment has been minimized.
5061893 to
0796771
Compare
54b85e5 to
590822c
Compare
114c81d to
17cd482
Compare
This comment has been minimized.
This comment has been minimized.
17cd482 to
8341948
Compare
chriseth
left a comment
There was a problem hiding this comment.
This is still a little too complicated for my taste and only works for libyul and not the classic optimizer.
Can you change the functions in RuleList.h to accept an EVMVersion parameter and then - in a regular simplificationRuleListPartN function add
if (_evmVersion.hasSelfbalance())
rules.push_back(...);
Please not that it should be hasSelfbalance and not a comparison for istanbul!
8341948 to
fece50c
Compare
This comment has been minimized.
This comment has been minimized.
fece50c to
e847940
Compare
This comment has been minimized.
This comment has been minimized.
e847940 to
ab36603
Compare
This comment has been minimized.
This comment has been minimized.
db79174 to
2ba82cc
Compare
libevmasm/RuleList.h
Outdated
| /// @returns a list of generic simplification rules with additional rules that may apply for the given dialect. | ||
| template <class Pattern> | ||
| std::vector<SimplificationRule<Pattern>> simplificationRuleList( | ||
| yul::Dialect const& _dialect, |
| return nullptr; | ||
|
|
||
| static SimplificationRules rules; | ||
| static SimplificationRules rules(_dialect); |
There was a problem hiding this comment.
This way, the rules list will always use the dialect it was first initialized with. You need a static (maybe LazyInit) variable of type std::map<EVMVersion, SimplificationRules>.
There was a problem hiding this comment.
Ah ok.. I thought that the compiler will only be initialized with exactly one EVMVersion..
There was a problem hiding this comment.
Never be sure about that :)
libevmasm/RuleList.h
Outdated
| Pattern Z | ||
| ) | ||
| { | ||
| std::vector<SimplificationRule<Pattern>> rules{simplificationRuleList(A, B, C, W, X, Y, Z)}; |
There was a problem hiding this comment.
Why don't you change that function instead?
There was a problem hiding this comment.
I thought it may make sense to separate evm version specific rules from generic rules
There was a problem hiding this comment.
In a way, we already have a lot of them mixed in, but they do not matter because they do not introduce a new opcode.
There was a problem hiding this comment.
Ah oki, I will change the function.
2ba82cc to
6753cb5
Compare
This comment has been minimized.
This comment has been minimized.
75982d0 to
b000af2
Compare
|
This is still missing the changes in the old optimizer. |
|
I'm working on this. |
b000af2 to
a5bedf3
Compare
leonardoalt
left a comment
There was a problem hiding this comment.
It'd be fun to add a test like
{
let a := address()
let ret := balance(a)
}
// ====
// EVMVersion: >=istanbul
// ----
// step: expressionSimplifier
//
// { let ret := selfbalance() }
Does the rule list work before or after the Yul optimizers in that case?
| if (yul::EVMDialect const* evmDialect = dynamic_cast<yul::EVMDialect const*>(&_dialect)) | ||
| version = evmDialect->evmVersion(); | ||
|
|
||
| if (evmRules.find(version) == evmRules.end()) |
There was a problem hiding this comment.
| if (evmRules.find(version) == evmRules.end()) | |
| if (!evmRules.count(version)) |
|
Oh sorry, forgot to comment here: It turned out that this is not really worth it for the old optimizer, because the rules cannot be used with the old optimizer. The old optimizer can only have rules with instructions that are deterministic. Since |
a5bedf3 to
a7b8906
Compare
|
Added the fun test. |
Fixes #7542, #8882