From 1eb8d8f10b6bc321548dbe4e8dc9fee67e47996f Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Tue, 6 Oct 2020 11:30:38 +0200 Subject: [PATCH] Split StackToMemoryMover into assignment+declaration and identifier movers. --- libyul/optimiser/StackToMemoryMover.cpp | 39 +++++++++++--------- libyul/optimiser/StackToMemoryMover.h | 48 +++++++++++++++++-------- 2 files changed, 55 insertions(+), 32 deletions(-) diff --git a/libyul/optimiser/StackToMemoryMover.cpp b/libyul/optimiser/StackToMemoryMover.cpp index db9bbef21..722c7a5b6 100644 --- a/libyul/optimiser/StackToMemoryMover.cpp +++ b/libyul/optimiser/StackToMemoryMover.cpp @@ -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(&_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>; auto containsVariableNeedingEscalation = [&](auto const& _variables) { @@ -120,7 +125,7 @@ void StackToMemoryMover::operator()(Block& _block) vector 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 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(&_expression)) if (optional offset = m_memoryOffsetTracker(identifier->name)) diff --git a/libyul/optimiser/StackToMemoryMover.h b/libyul/optimiser/StackToMemoryMover.h index 5cbc5a5a0..c26130b8d 100644 --- a/libyul/optimiser/StackToMemoryMover.h +++ b/libyul/optimiser/StackToMemoryMover.h @@ -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 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; + }; }; } \ No newline at end of file