Skip to content

[yul] Add support for EVM version-dependent rules.#8958

Merged
chriseth merged 1 commit intodevelopfrom
evm-version-dependent-rules
May 27, 2020
Merged

[yul] Add support for EVM version-dependent rules.#8958
chriseth merged 1 commit intodevelopfrom
evm-version-dependent-rules

Conversation

@aarlt
Copy link
Copy Markdown
Contributor

@aarlt aarlt commented May 16, 2020

Fixes #7542, #8882

@aarlt aarlt force-pushed the evm-version-dependent-rules branch from 6c87973 to 99768c2 Compare May 16, 2020 17:41
@stackenbotten

This comment has been minimized.

@aarlt aarlt force-pushed the evm-version-dependent-rules branch 2 times, most recently from 5061893 to 0796771 Compare May 17, 2020 14:47
@aarlt aarlt force-pushed the evm-version-dependent-rules branch 3 times, most recently from 54b85e5 to 590822c Compare May 18, 2020 14:22
@aarlt aarlt marked this pull request as ready for review May 18, 2020 16:40
@aarlt aarlt force-pushed the evm-version-dependent-rules branch 2 times, most recently from 114c81d to 17cd482 Compare May 19, 2020 05:26
@stackenbotten

This comment has been minimized.

@aarlt aarlt force-pushed the evm-version-dependent-rules branch from 17cd482 to 8341948 Compare May 19, 2020 05:36
Copy link
Copy Markdown
Contributor

@chriseth chriseth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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!

@aarlt aarlt force-pushed the evm-version-dependent-rules branch from 8341948 to fece50c Compare May 19, 2020 16:41
@stackenbotten

This comment has been minimized.

@aarlt aarlt force-pushed the evm-version-dependent-rules branch from fece50c to e847940 Compare May 19, 2020 16:45
@stackenbotten

This comment has been minimized.

@aarlt aarlt force-pushed the evm-version-dependent-rules branch from e847940 to ab36603 Compare May 19, 2020 16:47
@stackenbotten

This comment has been minimized.

@aarlt aarlt force-pushed the evm-version-dependent-rules branch 2 times, most recently from db79174 to 2ba82cc Compare May 19, 2020 17:14
/// @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,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah! Even better!

return nullptr;

static SimplificationRules rules;
static SimplificationRules rules(_dialect);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah ok.. I thought that the compiler will only be initialized with exactly one EVMVersion..

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Never be sure about that :)

Pattern Z
)
{
std::vector<SimplificationRule<Pattern>> rules{simplificationRuleList(A, B, C, W, X, Y, Z)};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't you change that function instead?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought it may make sense to separate evm version specific rules from generic rules

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah oki, I will change the function.

@aarlt aarlt force-pushed the evm-version-dependent-rules branch from 2ba82cc to 6753cb5 Compare May 19, 2020 19:27
@stackenbotten

This comment has been minimized.

@aarlt aarlt force-pushed the evm-version-dependent-rules branch 5 times, most recently from 75982d0 to b000af2 Compare May 19, 2020 21:18
@chriseth
Copy link
Copy Markdown
Contributor

This is still missing the changes in the old optimizer.

@chriseth
Copy link
Copy Markdown
Contributor

I'm working on this.

@chriseth chriseth force-pushed the evm-version-dependent-rules branch from b000af2 to a5bedf3 Compare May 20, 2020 10:40
Copy link
Copy Markdown

@leonardoalt leonardoalt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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())
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (evmRules.find(version) == evmRules.end())
if (!evmRules.count(version))

@chriseth
Copy link
Copy Markdown
Contributor

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 balance depends on previous calls, it is excluded.

@chriseth chriseth force-pushed the evm-version-dependent-rules branch from a5bedf3 to a7b8906 Compare May 27, 2020 09:57
@chriseth
Copy link
Copy Markdown
Contributor

Added the fun test.

@chriseth chriseth merged commit a06ac0f into develop May 27, 2020
@chriseth chriseth deleted the evm-version-dependent-rules branch May 27, 2020 10:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Yul] EVMVersion-dependent rules

6 participants