Skip to content

SSA CFG Codegen: make function return label slot handling explicit#16501

Merged
clonker merged 1 commit into
developfrom
ssa_cfg_codegen_with_explicit_return_slots
Mar 10, 2026
Merged

SSA CFG Codegen: make function return label slot handling explicit#16501
clonker merged 1 commit into
developfrom
ssa_cfg_codegen_with_explicit_return_slots

Conversation

@clonker

@clonker clonker commented Mar 5, 2026

Copy link
Copy Markdown
Member

The function return label (the address the callee jumps back to) is now tracked as an explicit FunctionReturnLabel slot on the virtual stack throughout a function's CFG, rather than being treated as an implicit/invisible slot below the tracked stack.

@clonker clonker added the has dependencies The PR depends on other PRs that must be merged first label Mar 5, 2026
@clonker clonker marked this pull request as ready for review March 5, 2026 14:49
@clonker clonker force-pushed the ssa_cfg_codegen_with_explicit_return_slots branch from d6c853e to 0b95d6a Compare March 5, 2026 15:10
@clonker clonker force-pushed the ssa_cfg_codegen_with_explicit_return_slots branch from 0b95d6a to a213789 Compare March 5, 2026 15:13
@clonker clonker force-pushed the ssa_cfg_codegen_with_explicit_return_slots branch from a213789 to 101f235 Compare March 5, 2026 15:15
@clonker clonker force-pushed the ssa_cfg_codegen_with_explicit_return_slots branch from 101f235 to 68b3040 Compare March 5, 2026 15:41
@clonker clonker force-pushed the ssa_cfg_codegen_with_explicit_return_slots branch from 68b3040 to a765904 Compare March 5, 2026 16:07
Base automatically changed from ssa_cfg_codegen to develop March 5, 2026 17:39
@clonker clonker force-pushed the ssa_cfg_codegen_with_explicit_return_slots branch from a765904 to 3782d10 Compare March 5, 2026 17:40
@clonker clonker requested review from blishko and r0qs March 9, 2026 09:12
@clonker clonker removed the has dependencies The PR depends on other PRs that must be merged first label Mar 9, 2026
@blishko

blishko commented Mar 10, 2026

Copy link
Copy Markdown
Contributor

Can you maybe explain in more detail what is the benefit of this explicit tracking? Or what is the problem with the current implicit approach?

I am having trouble understanding why is this even needed.

@clonker

clonker commented Mar 10, 2026

Copy link
Copy Markdown
Member Author

Can you maybe explain in more detail what is the benefit of this explicit tracking? Or what is the problem with the current implicit approach?

The implicit approach required the code transform to lie about stack heights and do manual shuffling at return sites, bypassing the layout generator. Making it explicit lets the existing layout/shuffle infrastructure handle it uniformly, which is simpler and eliminates a TODO:

m_assembly.setStackHeight(m_assembly.stackHeight() + 1);
// Build target: [rv1, rv2, ..., rvN-1, rv0] (rv0 at top).
// After shuffle: EVM = [label, rv1, ..., rvN-1, rv0].
// After SWAP(N): EVM = [rv0, rv1, ..., rvN-1, label].
// After JUMP: EVM = [rv0, rv1, ..., rvN-1].
// TODO: it would be better to account for function return labels from the entry of the function to the end symbolically
StackData returnTarget;
if (!_functionReturn.returnValues.empty())
{
returnTarget.reserve(_functionReturn.returnValues.size());
for (std::size_t i = 1; i < _functionReturn.returnValues.size(); ++i)
returnTarget.push_back(StackSlot::makeValueID(_functionReturn.returnValues[i]));
returnTarget.push_back(StackSlot::makeValueID(_functionReturn.returnValues.front()));
StackShuffler<AssemblyCallbacks>::shuffle(m_stack, returnTarget, {}, returnTarget.size());
m_assembly.appendInstruction(evmasm::swapInstruction(
static_cast<unsigned>(_functionReturn.returnValues.size())
));
}
else
StackShuffler<AssemblyCallbacks>::shuffle(m_stack, returnTarget, {}, 0);
m_assembly.appendJump(0, AbstractAssembly::JumpType::OutOfFunction);

Beyond that it also

  • makes things more explicit, which at least I like stylistically; and
  • for shuffling it can be advantageous, too: right now the return label slot is invisible and pinned beneath the function call stack. After this change it is visible to the shuffler as regular slot and can be placed intermittently elsewhere, so we gain flexibility.

@blishko blishko left a comment

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.

Seems good to me! I have some questions about the changes in the tests.

Comment thread test/libyul/ssa/stackLayoutGenerator/function.yul
Comment thread test/libyul/ssa/stackLayoutGenerator/recursion.yul
@clonker clonker force-pushed the ssa_cfg_codegen_with_explicit_return_slots branch from 3782d10 to fd17507 Compare March 10, 2026 09:10

@blishko blishko left a comment

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.

LGTM!

@clonker clonker force-pushed the ssa_cfg_codegen_with_explicit_return_slots branch from a75dd5e to 64e221f Compare March 10, 2026 12:01
@clonker clonker merged commit 47875c8 into develop Mar 10, 2026
83 checks passed
@clonker clonker deleted the ssa_cfg_codegen_with_explicit_return_slots branch March 10, 2026 12:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants