mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Have the stack optimization in the code transform only reuse slots that are reachable and fix argument slot reuse on functions without return variables.
This commit is contained in:
parent
dfce7b667d
commit
bc288aacf5
@ -182,16 +182,24 @@ void CodeTransform::operator()(VariableDeclaration const& _varDecl)
|
|||||||
else
|
else
|
||||||
m_variablesScheduledForDeletion.insert(&var);
|
m_variablesScheduledForDeletion.insert(&var);
|
||||||
}
|
}
|
||||||
else if (m_unusedStackSlots.empty())
|
|
||||||
atTopOfStack = false;
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto slot = static_cast<size_t>(*m_unusedStackSlots.begin());
|
bool foundUnusedSlot = false;
|
||||||
m_unusedStackSlots.erase(m_unusedStackSlots.begin());
|
for (auto it = m_unusedStackSlots.begin(); it != m_unusedStackSlots.end(); ++it)
|
||||||
m_context->variableStackHeights[&var] = slot;
|
{
|
||||||
if (size_t heightDiff = variableHeightDiff(var, varName, true))
|
if (m_assembly.stackHeight() - *it > 17)
|
||||||
m_assembly.appendInstruction(evmasm::swapInstruction(static_cast<unsigned>(heightDiff - 1)));
|
continue;
|
||||||
m_assembly.appendInstruction(evmasm::Instruction::POP);
|
foundUnusedSlot = true;
|
||||||
|
auto slot = static_cast<size_t>(*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<unsigned>(heightDiff - 1)));
|
||||||
|
m_assembly.appendInstruction(evmasm::Instruction::POP);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!foundUnusedSlot)
|
||||||
|
atTopOfStack = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -404,7 +412,7 @@ void CodeTransform::operator()(FunctionDefinition const& _function)
|
|||||||
subTransform.deleteVariable(var);
|
subTransform.deleteVariable(var);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_allowStackOpt || _function.returnVariables.empty())
|
if (!m_allowStackOpt)
|
||||||
subTransform.setupReturnVariablesAndFunctionExit();
|
subTransform.setupReturnVariablesAndFunctionExit();
|
||||||
|
|
||||||
subTransform(_function.body);
|
subTransform(_function.body);
|
||||||
@ -594,6 +602,7 @@ void CodeTransform::visitExpression(Expression const& _expression)
|
|||||||
|
|
||||||
void CodeTransform::setupReturnVariablesAndFunctionExit()
|
void CodeTransform::setupReturnVariablesAndFunctionExit()
|
||||||
{
|
{
|
||||||
|
yulAssert(isInsideFunction(), "");
|
||||||
yulAssert(!returnVariablesAndFunctionExitAreSetup(), "");
|
yulAssert(!returnVariablesAndFunctionExitAreSetup(), "");
|
||||||
yulAssert(m_scope, "");
|
yulAssert(m_scope, "");
|
||||||
|
|
||||||
@ -656,7 +665,8 @@ void CodeTransform::visitStatements(vector<Statement> const& _statements)
|
|||||||
{
|
{
|
||||||
freeUnusedVariables();
|
freeUnusedVariables();
|
||||||
if (
|
if (
|
||||||
!m_delayedReturnVariables.empty() &&
|
isInsideFunction() &&
|
||||||
|
!returnVariablesAndFunctionExitAreSetup() &&
|
||||||
statementNeedsReturnVariableSetup(statement, m_delayedReturnVariables)
|
statementNeedsReturnVariableSetup(statement, m_delayedReturnVariables)
|
||||||
)
|
)
|
||||||
setupReturnVariablesAndFunctionExit();
|
setupReturnVariablesAndFunctionExit();
|
||||||
|
@ -181,6 +181,10 @@ private:
|
|||||||
{
|
{
|
||||||
return m_functionExitStackHeight.has_value();
|
return m_functionExitStackHeight.has_value();
|
||||||
}
|
}
|
||||||
|
bool isInsideFunction() const
|
||||||
|
{
|
||||||
|
return m_functionExitLabel.has_value();
|
||||||
|
}
|
||||||
|
|
||||||
AbstractAssembly& m_assembly;
|
AbstractAssembly& m_assembly;
|
||||||
AsmAnalysisInfo& m_info;
|
AsmAnalysisInfo& m_info;
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
function f(x, y) {
|
||||||
|
mstore(0x80, x)
|
||||||
|
if calldataload(0) { sstore(y, y) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ====
|
||||||
|
// stackOptimization: true
|
||||||
|
// ----
|
||||||
|
// PUSH1 0x17
|
||||||
|
// JUMP
|
||||||
|
// JUMPDEST
|
||||||
|
// DUP1
|
||||||
|
// PUSH1 0x80
|
||||||
|
// MSTORE
|
||||||
|
// POP
|
||||||
|
// PUSH1 0x0
|
||||||
|
// CALLDATALOAD
|
||||||
|
// ISZERO
|
||||||
|
// PUSH1 0x13
|
||||||
|
// JUMPI
|
||||||
|
// DUP1
|
||||||
|
// DUP2
|
||||||
|
// SSTORE
|
||||||
|
// JUMPDEST
|
||||||
|
// POP
|
||||||
|
// JUMPDEST
|
||||||
|
// JUMP
|
||||||
|
// JUMPDEST
|
Loading…
Reference in New Issue
Block a user