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, uint64_t _numRequiredSlots,
Block& _block 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); auto const* evmDialect = dynamic_cast<EVMDialect const*>(&_context.dialect);
yulAssert( yulAssert(
evmDialect && evmDialect->providesObjectAccess(), evmDialect && evmDialect->providesObjectAccess(),
"StackToMemoryMover can only be run on objects using the EVMDialect with object access." "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) for (TypedName const& param: _functionDefinition.parameters + _functionDefinition.returnVariables)
if (m_memoryOffsetTracker(param.name)) if (m_memoryOffsetTracker(param.name))
@ -90,7 +84,18 @@ void StackToMemoryMover::operator()(FunctionDefinition& _functionDefinition)
ASTModifier::operator()(_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>>; using OptionalStatements = std::optional<vector<Statement>>;
auto containsVariableNeedingEscalation = [&](auto const& _variables) { auto containsVariableNeedingEscalation = [&](auto const& _variables) {
@ -120,7 +125,7 @@ void StackToMemoryMover::operator()(Block& _block)
vector<Statement> variableAssignments; vector<Statement> variableAssignments;
for (auto& var: _variables) 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, {}}); tempDecl.variables.emplace_back(TypedName{var.location, tempVarName, {}});
if (optional<YulString> offset = m_memoryOffsetTracker(var.name)) 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 (Identifier* identifier = std::get_if<Identifier>(&_expression))
if (optional<YulString> offset = m_memoryOffsetTracker(identifier->name)) if (optional<YulString> offset = m_memoryOffsetTracker(identifier->name))

View File

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