-
Notifications
You must be signed in to change notification settings - Fork 5.9k
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
[Sol->Yul] Implementing delete struct #9843
Conversation
a281168
to
233266d
Compare
233266d
to
165b042
Compare
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.
Add test that deletes array of structs
165b042
to
f6912ed
Compare
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.
Some minor comments and remarks, but in general this looks good now.
I think this mainly depends on #9914 now for the recursive struct test? I'll look at that next in any case.
f6912ed
to
7720a0a
Compare
7720a0a
to
9e3ad59
Compare
I think #9914 will help activating recursive struct case. So, once it is merged, will do another check for that case. |
e14e244
to
2e7ec99
Compare
After merging #9914 I needed to implement conversion from |
2cd3c68
to
14faccd
Compare
|
||
set<u256> slotsCleared; | ||
for (auto const& member: structMembers) | ||
if (member.type->storageBytes() < 32) |
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.
Can you extract this part into its own PR?
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.
You mean the whole function?
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.
The first optimizing case.
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.
I removed it from here. Will open another PR with optimization.
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.
#9985 is where I extracted optimizing case. Also it targets this branch as it depends on this one.
4609719
to
cf799f4
Compare
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.
One tiny coding style comment, but otherwise I'd say this is good to go (and due to the tinyness of the comment I'm already approving).
cf799f4
to
d6007aa
Compare
@ekpyron Can you re-approve :) |
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.
Reapproving.
@@ -2741,11 +2785,24 @@ string YulUtilFunctions::storageSetToZeroFunction(Type const& _type) | |||
else if (_type.category() == Type::Category::Array) | |||
return Whiskers(R"( | |||
function <functionName>(slot, offset) { | |||
if iszero(eq(offset, 0)) { <panic>() } |
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.
Is there no way to ensure that at compile time?
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.
Here it is not possible actually. I'll check all the places where this is called. If we can ensure there, maybe we can remove this check.
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.
Yeah, I see the problem. Maybe let's keep it then and try to tune the optimizer.
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.
Hm, all the places where this is called it is set either from C++ variable which can be checked for equal to zero in case of ref types, or is hardcoded to 0
Maybe it is the best to remove checks at all?
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.
The proper way to avoid the check here would be to have another version of this that just doesn't take an offset as argument and call that whenever the offset is statically zero - but that'd be quite some refactoring and complication in several layers above this - so I'd just keep the check and hope for the optimizer for now.
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.
So maybe we could revamp the function parameter removal steps we already have.
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.
all non-reverting code paths of a function set a return variable to a certain constant value -> remove the return variable from the function and set it at call sites (similar to return variable elimination)
all calls to a function set a parameter to the same constant value: remove the parameter and assign the
We could widen this from "constant values" to "movable value of low cost", if we're careful enough.
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.
I mean ideally this would even generalize to splitting any
function f() -> a, b {
{
a := ...expensive calculation...
}
{
b := ...expensive calculation...
}
}
Into
function f() -> a, b { a := f1() b := f2() }
function f1() -> a { a := ... }
function f2() -> b { b := ... }
which in the constant case (e.g. a := 42
) will have f1()
and then f
inlined and reduce to moving constants out that way...
I think that may be the most reasonable alternative to the "outlining" idea we once had...
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.
But it'll be tricky to figure out when this is possible, since in general the calculations will be interleaved, etc. So probably best to find a reasonable subset of cases to start - but maybe more general than just constants :-).
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.
If we follow that path, this would be headed towards the old optimizer reconstructing values based on data flow analysis :-). But that's not necessarily a bad thing IMO.
d2b7831
to
e807fd2
Compare
741a527
to
197ed10
Compare
)")("abiDecode", ABIFunctions(m_evmVersion, m_revertStrings, m_functionCollector).tupleDecoder( | ||
{&toStructType} | ||
)).render(); | ||
solUnimplementedAssert(toStructType.sizeOnStack() == 1 && fromStructType.sizeOnStack() == 1, ""); |
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.
Just because we were messing with this simultanously, so maybe otherwise the comment will get lost ;-):
I think this rather belongs in L2184 right when the function signature is first created.
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.
(Then based on _from.sizeOnStack()
and _to.sizeOnStack()
- but that's the place that will really be hit, if they're not both one)
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.
I added it. But does it really makes sense, as there is a call before this:
if (_from.sizeOnStack() != 1 || _to.sizeOnStack() != 1)
return conversionFunctionSpecial(_from, _to);
maybe solAssert
instead?
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.
Ah, I didn't see that - that's a rather unfortunate distinction and scatters the array conversions all over the place... we should think about changing this in the future, but not in this PR :-).
But we can just drop the assertion in this case, it was overdoing it anyways.
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.
Ah, I didn't see that - that's a rather unfortunate distinction and scatters the array conversions all over the place... we should think about changing this in the future, but not in this PR :-).
But we can just drop the assertion in this case, it was overdoing it anyways.
Yes, it looks very unfortunate...
Once I finish copying of arrays to storage will maybe take a look at this and do the refactor.
197ed10
to
82cf03c
Compare
82cf03c
to
24272e6
Compare
Co-authored-by: Daniel Kirchner <daniel@ekpyron.org>
24272e6
to
ad8d840
Compare
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.
I looked through this five times now, because I'm a bit suspicious because I expected this to enable more conversion-related-tests apart from the deletion tests, but it probably depends on some of the others and I think it's fine now, I hope I'm not missing anything :-).
I think most of the tests start with copying to storage, and that's one thing we have not implemented yet. |
Yeah, I hope so, too. |
I am sneaking in support for recursive functions in
MultiUseYulFunctionCollector
as it is needed for recursive structs. If there is some better way to solve this, I am willing to change that :)Depends on #9914