mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Track unreachable variables globally instead of per function.
This commit is contained in:
parent
756e21a888
commit
0b87849bcb
@ -66,14 +66,13 @@ struct MemoryOffsetAllocator
|
||||
if (unreachableVariables.count(_function))
|
||||
{
|
||||
yulAssert(!slotAllocations.count(_function), "");
|
||||
auto& assignedSlots = slotAllocations[_function];
|
||||
for (YulString variable: unreachableVariables.at(_function))
|
||||
if (variable.empty())
|
||||
{
|
||||
// TODO: Too many function arguments or return parameters.
|
||||
}
|
||||
else
|
||||
assignedSlots[variable] = requiredSlots++;
|
||||
slotAllocations[variable] = requiredSlots++;
|
||||
}
|
||||
|
||||
return slotsRequiredForFunction[_function] = requiredSlots;
|
||||
@ -82,7 +81,7 @@ struct MemoryOffsetAllocator
|
||||
map<YulString, set<YulString>> const& unreachableVariables;
|
||||
map<YulString, set<YulString>> const& callGraph;
|
||||
|
||||
map<YulString, map<YulString, uint64_t>> slotAllocations{};
|
||||
map<YulString, uint64_t> slotAllocations{};
|
||||
map<YulString, uint64_t> slotsRequiredForFunction{};
|
||||
};
|
||||
|
||||
|
@ -54,7 +54,7 @@ vector<Statement> generateMemoryStore(
|
||||
void StackToMemoryMover::run(
|
||||
OptimiserStepContext& _context,
|
||||
u256 _reservedMemory,
|
||||
map<YulString, map<YulString, uint64_t>> const& _memorySlots,
|
||||
map<YulString, uint64_t> const& _memorySlots,
|
||||
uint64_t _numRequiredSlots,
|
||||
Block& _block
|
||||
)
|
||||
@ -66,7 +66,7 @@ void StackToMemoryMover::run(
|
||||
StackToMemoryMover::StackToMemoryMover(
|
||||
OptimiserStepContext& _context,
|
||||
u256 _reservedMemory,
|
||||
map<YulString, map<YulString, uint64_t>> const& _memorySlots,
|
||||
map<YulString, uint64_t> const& _memorySlots,
|
||||
uint64_t _numRequiredSlots
|
||||
):
|
||||
m_context(_context),
|
||||
@ -80,41 +80,25 @@ m_nameDispenser(_context.dispenser)
|
||||
evmDialect && evmDialect->providesObjectAccess(),
|
||||
"StackToMemoryMover can only be run on objects using the EVMDialect with object access."
|
||||
);
|
||||
|
||||
if (m_memorySlots.count(YulString{}))
|
||||
// If the global scope contains variables to be moved, start with those as if it were a function.
|
||||
m_currentFunctionMemorySlots = &m_memorySlots.at(YulString{});
|
||||
}
|
||||
|
||||
void StackToMemoryMover::operator()(FunctionDefinition& _functionDefinition)
|
||||
{
|
||||
if (m_memorySlots.count(_functionDefinition.name))
|
||||
{
|
||||
map<YulString, uint64_t> const* saved = m_currentFunctionMemorySlots;
|
||||
m_currentFunctionMemorySlots = &m_memorySlots.at(_functionDefinition.name);
|
||||
for (TypedName const& param: _functionDefinition.parameters + _functionDefinition.returnVariables)
|
||||
if (m_currentFunctionMemorySlots->count(param.name))
|
||||
{
|
||||
// TODO: we cannot handle function parameters yet.
|
||||
m_currentFunctionMemorySlots = saved;
|
||||
return;
|
||||
}
|
||||
ASTModifier::operator()(_functionDefinition);
|
||||
m_currentFunctionMemorySlots = saved;
|
||||
}
|
||||
for (TypedName const& param: _functionDefinition.parameters + _functionDefinition.returnVariables)
|
||||
if (m_memorySlots.count(param.name))
|
||||
{
|
||||
// TODO: we cannot handle function parameters yet.
|
||||
return;
|
||||
}
|
||||
ASTModifier::operator()(_functionDefinition);
|
||||
}
|
||||
|
||||
void StackToMemoryMover::operator()(Block& _block)
|
||||
{
|
||||
using OptionalStatements = std::optional<vector<Statement>>;
|
||||
if (!m_currentFunctionMemorySlots)
|
||||
{
|
||||
ASTModifier::operator()(_block);
|
||||
return;
|
||||
}
|
||||
auto containsVariableNeedingEscalation = [&](auto const& _variables) {
|
||||
return util::contains_if(_variables, [&](auto const& var) {
|
||||
return m_currentFunctionMemorySlots->count(var.name);
|
||||
return m_memorySlots.count(var.name);
|
||||
});
|
||||
};
|
||||
auto rewriteAssignmentOrVariableDeclaration = [&](
|
||||
@ -138,7 +122,7 @@ void StackToMemoryMover::operator()(Block& _block)
|
||||
YulString tempVarName = m_nameDispenser.newName(var.name);
|
||||
tempDecl.variables.emplace_back(TypedName{var.location, tempVarName, {}});
|
||||
|
||||
if (m_currentFunctionMemorySlots->count(var.name))
|
||||
if (m_memorySlots.count(var.name))
|
||||
memoryAssignments += generateMemoryStore(
|
||||
m_context.dialect,
|
||||
_loc,
|
||||
@ -203,7 +187,7 @@ void StackToMemoryMover::visit(Expression& _expression)
|
||||
{
|
||||
if (
|
||||
Identifier* identifier = std::get_if<Identifier>(&_expression);
|
||||
identifier && m_currentFunctionMemorySlots && m_currentFunctionMemorySlots->count(identifier->name)
|
||||
identifier && m_memorySlots.count(identifier->name)
|
||||
)
|
||||
{
|
||||
BuiltinFunction const* memoryLoadFunction = m_context.dialect.memoryLoadFunction(m_context.dialect.defaultType);
|
||||
@ -227,8 +211,8 @@ void StackToMemoryMover::visit(Expression& _expression)
|
||||
|
||||
YulString StackToMemoryMover::memoryOffset(YulString _variable)
|
||||
{
|
||||
yulAssert(m_currentFunctionMemorySlots, "");
|
||||
uint64_t slot = m_currentFunctionMemorySlots->at(_variable);
|
||||
yulAssert(m_memorySlots.count(_variable), "");
|
||||
uint64_t slot = m_memorySlots.at(_variable);
|
||||
yulAssert(slot < m_numRequiredSlots, "");
|
||||
return YulString{util::toCompactHexWithPrefix(m_reservedMemory + 32 * (m_numRequiredSlots - slot - 1))};
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ public:
|
||||
static void run(
|
||||
OptimiserStepContext& _context,
|
||||
u256 _reservedMemory,
|
||||
std::map<YulString, std::map<YulString, uint64_t>> const& _memorySlots,
|
||||
std::map<YulString, uint64_t> const& _memorySlots,
|
||||
uint64_t _numRequiredSlots,
|
||||
Block& _block
|
||||
);
|
||||
@ -103,7 +103,7 @@ private:
|
||||
StackToMemoryMover(
|
||||
OptimiserStepContext& _context,
|
||||
u256 _reservedMemory,
|
||||
std::map<YulString, std::map<YulString, uint64_t>> const& _memorySlots,
|
||||
std::map<YulString, uint64_t> const& _memorySlots,
|
||||
uint64_t _numRequiredSlots
|
||||
);
|
||||
|
||||
@ -112,10 +112,9 @@ private:
|
||||
|
||||
OptimiserStepContext& m_context;
|
||||
u256 m_reservedMemory;
|
||||
std::map<YulString, std::map<YulString, uint64_t>> const& m_memorySlots;
|
||||
std::map<YulString, uint64_t> const& m_memorySlots;
|
||||
uint64_t m_numRequiredSlots = 0;
|
||||
NameDispenser& m_nameDispenser;
|
||||
std::map<YulString, uint64_t> const* m_currentFunctionMemorySlots = nullptr;
|
||||
};
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user