From f1a474e599944fa59c04d75a3f44dde55c893871 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Tue, 13 Apr 2021 22:25:13 +0200 Subject: [PATCH] Have the stack optimization in the code transform only reuse slots that are reachable. --- libyul/backends/evm/EVMCodeTransform.cpp | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/libyul/backends/evm/EVMCodeTransform.cpp b/libyul/backends/evm/EVMCodeTransform.cpp index e357a071c..8c8efe46d 100644 --- a/libyul/backends/evm/EVMCodeTransform.cpp +++ b/libyul/backends/evm/EVMCodeTransform.cpp @@ -172,16 +172,24 @@ void CodeTransform::operator()(VariableDeclaration const& _varDecl) else m_variablesScheduledForDeletion.insert(&var); } - else if (m_unusedStackSlots.empty()) - atTopOfStack = false; else { - auto slot = static_cast(*m_unusedStackSlots.begin()); - m_unusedStackSlots.erase(m_unusedStackSlots.begin()); - m_context->variableStackHeights[&var] = slot; - if (size_t heightDiff = variableHeightDiff(var, varName, true)) - m_assembly.appendInstruction(evmasm::swapInstruction(static_cast(heightDiff - 1))); - m_assembly.appendInstruction(evmasm::Instruction::POP); + bool foundUnusedSlot = false; + for (auto it = m_unusedStackSlots.begin(); it != m_unusedStackSlots.end(); ++it) + { + if (m_assembly.stackHeight() - *it > 17) + continue; + foundUnusedSlot = true; + auto slot = static_cast(*it); + m_unusedStackSlots.erase(it); + m_context->variableStackHeights[&var] = slot; + if (size_t heightDiff = variableHeightDiff(var, varName, true)) + m_assembly.appendInstruction(evmasm::swapInstruction(static_cast(heightDiff - 1))); + m_assembly.appendInstruction(evmasm::Instruction::POP); + break; + } + if (!foundUnusedSlot) + atTopOfStack = false; } } }