Split StackToMemoryMover into assignment+declaration and identifier movers.

This commit is contained in:
Daniel Kirchner 2020-10-06 11:30:38 +02:00
parent c8a7098f2f
commit 1eb8d8f10b
2 changed files with 55 additions and 32 deletions

View File

@ -58,28 +58,22 @@ void StackToMemoryMover::run(
uint64_t _numRequiredSlots,
Block& _block
)
{
VariableMemoryOffsetTracker memoryOffsetTracker(_reservedMemory, _memorySlots, _numRequiredSlots);
StackToMemoryMover stackToMemoryMover(_context, memoryOffsetTracker);
stackToMemoryMover(_block);
}
StackToMemoryMover::StackToMemoryMover(
OptimiserStepContext& _context,
VariableMemoryOffsetTracker const& _memoryOffsetTracker
):
m_context(_context),
m_memoryOffsetTracker(_memoryOffsetTracker),
m_nameDispenser(_context.dispenser)
{
auto const* evmDialect = dynamic_cast<EVMDialect const*>(&_context.dialect);
yulAssert(
evmDialect && evmDialect->providesObjectAccess(),
"StackToMemoryMover can only be run on objects using the EVMDialect with object access."
);
VariableMemoryOffsetTracker memoryOffsetTracker(_reservedMemory, _memorySlots, _numRequiredSlots);
VariableDeclarationAndAssignmentMover declarationAndAssignmentMover(_context, memoryOffsetTracker);
declarationAndAssignmentMover(_block);
IdentifierMover identifierMover(_context, memoryOffsetTracker);
identifierMover(_block);
}
void StackToMemoryMover::operator()(FunctionDefinition& _functionDefinition)
void StackToMemoryMover::VariableDeclarationAndAssignmentMover::operator()(FunctionDefinition& _functionDefinition)
{
for (TypedName const& param: _functionDefinition.parameters + _functionDefinition.returnVariables)
if (m_memoryOffsetTracker(param.name))
@ -90,7 +84,18 @@ void StackToMemoryMover::operator()(FunctionDefinition& _functionDefinition)
ASTModifier::operator()(_functionDefinition);
}
void StackToMemoryMover::operator()(Block& _block)
void StackToMemoryMover::IdentifierMover::operator()(FunctionDefinition& _functionDefinition)
{
for (TypedName const& param: _functionDefinition.parameters + _functionDefinition.returnVariables)
if (m_memoryOffsetTracker(param.name))
{
// TODO: we cannot handle function parameters yet.
return;
}
ASTModifier::operator()(_functionDefinition);
}
void StackToMemoryMover::VariableDeclarationAndAssignmentMover::operator()(Block& _block)
{
using OptionalStatements = std::optional<vector<Statement>>;
auto containsVariableNeedingEscalation = [&](auto const& _variables) {
@ -120,7 +125,7 @@ void StackToMemoryMover::operator()(Block& _block)
vector<Statement> variableAssignments;
for (auto& var: _variables)
{
YulString tempVarName = m_nameDispenser.newName(var.name);
YulString tempVarName = m_context.dispenser.newName(var.name);
tempDecl.variables.emplace_back(TypedName{var.location, tempVarName, {}});
if (optional<YulString> offset = m_memoryOffsetTracker(var.name))
@ -184,7 +189,7 @@ void StackToMemoryMover::operator()(Block& _block)
});
}
void StackToMemoryMover::visit(Expression& _expression)
void StackToMemoryMover::IdentifierMover::visit(Expression& _expression)
{
if (Identifier* identifier = std::get_if<Identifier>(&_expression))
if (optional<YulString> offset = m_memoryOffsetTracker(identifier->name))

View File

@ -75,7 +75,7 @@ namespace solidity::yul
*
* Prerequisite: Disambiguator, ForLoopInitRewriter, FunctionHoister.
*/
class StackToMemoryMover: ASTModifier
class StackToMemoryMover
{
public:
/**
@ -94,11 +94,6 @@ public:
uint64_t _numRequiredSlots,
Block& _block
);
using ASTModifier::operator();
void operator()(FunctionDefinition& _functionDefinition) override;
void operator()(Block& _block) override;
void visit(Expression& _expression) override;
private:
class VariableMemoryOffsetTracker
{
@ -118,15 +113,38 @@ private:
std::map<YulString, uint64_t> const& m_memorySlots;
uint64_t m_numRequiredSlots = 0;
};
StackToMemoryMover(
OptimiserStepContext& _context,
VariableMemoryOffsetTracker const& _memoryOffsetTracker
);
OptimiserStepContext& m_context;
VariableMemoryOffsetTracker const& m_memoryOffsetTracker;
NameDispenser& m_nameDispenser;
class VariableDeclarationAndAssignmentMover: ASTModifier
{
public:
VariableDeclarationAndAssignmentMover(
OptimiserStepContext& _context,
VariableMemoryOffsetTracker const& _memoryOffsetTracker
): m_context(_context), m_memoryOffsetTracker(_memoryOffsetTracker)
{
}
using ASTModifier::operator();
void operator()(FunctionDefinition& _functionDefinition) override;
void operator()(Block& _block) override;
private:
OptimiserStepContext& m_context;
VariableMemoryOffsetTracker const& m_memoryOffsetTracker;
};
class IdentifierMover: ASTModifier
{
public:
IdentifierMover(
OptimiserStepContext& _context,
VariableMemoryOffsetTracker const& _memoryOffsetTracker
): m_context(_context), m_memoryOffsetTracker(_memoryOffsetTracker)
{
}
using ASTModifier::operator();
void operator()(FunctionDefinition& _functionDefinition) override;
void visit(Expression& _expression) override;
private:
OptimiserStepContext& m_context;
VariableMemoryOffsetTracker const& m_memoryOffsetTracker;
};
};
}