-
Notifications
You must be signed in to change notification settings - Fork 6.1k
Performance: Common Subexpression Eliminator Speedup #16741
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from 5 commits
dd29fcf
0c74952
ac9ae2f
eafecc1
71af112
12e044b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,6 +31,8 @@ | |
| #include <libyul/Dialect.h> | ||
| #include <libyul/Utilities.h> | ||
|
|
||
| #include <algorithm> | ||
|
|
||
| using namespace solidity; | ||
| using namespace solidity::yul; | ||
| using namespace solidity::util; | ||
|
|
@@ -129,6 +131,10 @@ void CommonSubexpressionEliminator::visit(Expression& _e) | |
| void CommonSubexpressionEliminator::assignValue(YulName _variable, Expression const* _value) | ||
| { | ||
| if (_value) | ||
| m_replacementCandidates[*_value].insert(_variable); | ||
| { | ||
| auto& candidates = m_replacementCandidates[*_value]; | ||
| if (std::find(candidates.begin(), candidates.end(), _variable) == candidates.end()) | ||
| candidates.emplace_back(_variable); | ||
|
Comment on lines
+135
to
+137
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will affect the order in which candidates are iterated in, so could/will affect the bytecode in the sense that it may now pick a different (although still valid) (sub)expression to be substituted. There are no guarantees on our side as to what the bytecode will actually look like as long as it's semantically correct, so I'm pretty sure this isn't a problem. @cameel can you double check please - this is the only change where I'm slightly uncertain?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Even if the candidates vector were unordered, this check is just checking for presence, which is deterministic regardless of order.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We're still iterating over the values in the vector (previously set), and the two have different iteration orders (set sort vs insertion), which makes it possible for different (but equivalent) expressions/values to be used as replacements. I'm not saying this is wrong or undesired behaviour, just that it could result in different bytecode between the two approaches, which is why I asked @cameel to double check. From my point of view, this is perfectly fine (but I have been wrong before).
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In pseudo javascript:
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah - now I understand! The set might have been sorted by something different than its insertion order, even if both are deterministic.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the important bit is not backwards compatible bytecode, but consistent bytecode output for this compiler version. In that case, a different sorting order would be fine, as long as it's deterministic. And this is definitely that. That said, no tests have needed to change as a result of this, and my local benchmarking on a set of real world contracts has identical bytecode out with this change, as without it. |
||
| } | ||
| DataFlowAnalyzer::assignValue(_variable, _value); | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, should probably mention that this particular improvement is due to optimizations in the CSE and dataflow analysis. In any case, let's wait until @cameel takes a look, he'll probably suggest a final version of the changelog entry phrasing.