Hi,
As per Documentation on Access Sets for EIP-2929 we have the concept of warm vs. cold SLOADs based on access sets.
We can see that a warm SLOAD costs 100 gas vs the 2100 for an untouched slot.
I also reviewed memory expansion, I think Blake from Goldfinch sums it up nicely when he says that, in most situations, optimising to avoid touching storage, where possible, is the real driver of gas optimisations.
With all that in mind, I’m wondering if it’s possible for the compiler to make some optimisations (maybe it already does! In which case would love to know more!) when we have repeated reads from storage.
In particular: I would love the compiler to be able to optimize my gas usage by caching every SLOAD that is read more than once.
Here’s an example where I would love this (apologies for syntax errors this is mostly pseudocode)
// assume we're inside a contract
CustomStruct {
bool validated;
bytes32 data;
}
mapping(address => CustomStruct) public userStructs;
modifier checkInnerValue() {
require(userStructs[msg.sender].validated, ":(");
_;
}
function doStuff() external checkInnerValue {
if (userStructs[msg.sender].validated) {
// do something
}
// blah blah blah
}
In the above example, we access the validated
property of the struct multiple times, once in the modifier, once in the function body.
A potential optimisation would be to declare an in-memory variable and then move the modifier logic into the function.
bool validated = userStructs[msg.sender].validated;
// inline the modifier inside the function body
My issue is more from readability - I personally quite like being able to reuse code inside modifiers, especially guard clauses that don’t really have much to do with the primary logic of the function. It would be amazing if the compiler, seeing that validated
is accessed > 1 times, essentially expands and inlines the function for me, caching the variable in memory and saving the warm SLOAD.
I understand there are limitations to this, in particular with regards to reentrancy concerns or writes to the same storage slot as part of a transaction, but I wanted to understand if the above makes sense and if it is already something that has been discussed.