SSA CFG: stack to memory spilling#16767
Conversation
| { | ||
| public: | ||
| static std::unique_ptr<TestCase> create(Config const& _config); | ||
| explicit SpillTest(std::string const& _filename); |
There was a problem hiding this comment.
Can/should this constructor be private?
There was a problem hiding this comment.
Not if we want to use make_unique in create, that can't access private ctors
There was a problem hiding this comment.
Right, that's true.
But you can change the implementation to
std::unique_ptr<frontend::test::TestCase> SpillTest::create(Config const& _config)
{
return std::unique_ptr<SpillTest>(new SpillTest(_config.filename));
}
And then you can make it private.
I had another look at the codebase and I see that that you are just following the existing pattern.
It's just that I don't understand the purpose of the pattern.
| std::deque<InstId>& _workQueue) | ||
| { | ||
| // Leaf predicate = spill set minus the owner; the shuffle accumulates discovered culprits here. | ||
| SpillSet leafSpills = without(_value); |
There was a problem hiding this comment.
Why leaf? I am not sure about the terminology.
| u256 const originalGuard = *_cfgs.memoryGuard; | ||
| *_cfgs.memoryGuard += u256(totalSlots) * 32; |
There was a problem hiding this comment.
Updating the memory guard in the constructor of MemoryAddressing is a bit suspicious to me.
I understand the intent, I think maybe we should design this differently.
Can we discuss this further?
| MemoryAddressing const* m_addressing; | ||
| FunctionGraphID m_cfgIdx; | ||
| SpillSet const* m_spillSet; | ||
| SSACFG const* m_cfg; | ||
| AbstractAssembly* m_assembly; |
| namespace solidity::yul::ssa::spill | ||
| { | ||
|
|
||
| class Emitter |
There was a problem hiding this comment.
I have to think somewhat more about this class.
b93b4ac to
821b1df
Compare
Implements stack to memory spilling for the SSA CFG pipeline in a simple stupid version.
Adds:
ssa/spill/MemoryAddressingis a per-subobject owner of spill memorynumSpilled()across each CFGsSpillSetand bumps memory guard accordingly, allocates non-overlapping memory addresses for spilled valuesssa/spill/Emitteremits bytecode against the symbolic stack for spilled valuesssa/spill/SpillSetgot a new methodfeasilizewhich will check for all spilled values whether they can be feasibly spilled at the point of origin, may add more things to spill accordinglyModifies
ssa/StackLayoutGeneratorsgenerate()to return{layout, spillSet}instead of just the layout and also validates back-edges asserting that back-edge targets can be safely shuffled tossa/CodeTransformis reworked to first generate per-CFG layouts and spill sets (feasilize them), then build a single globalMemoryAddressingto hand into theCodeTransforminstanceTest
SpillTestsuite undertest/libyul/ssa/spillwhich runs thegenerate->feasilize->addresssequence and emits that plus a text representation of the input object. does not generate any code.