Skip to content

Commit 7c8ad7a

Browse files
authored
Merge pull request #12239 from ethereum/preregisterfunction
Preregister functions
2 parents 735550b + 929ed09 commit 7c8ad7a

File tree

2 files changed

+34
-23
lines changed

2 files changed

+34
-23
lines changed

libyul/backends/evm/ControlFlowGraphBuilder.cpp

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -176,9 +176,9 @@ StackSlot ControlFlowGraphBuilder::operator()(Expression const& _expression)
176176

177177
StackSlot ControlFlowGraphBuilder::operator()(FunctionCall const& _call)
178178
{
179-
CFG::Operation const& operation = visitFunctionCall(_call);
180-
yulAssert(operation.output.size() == 1, "");
181-
return operation.output.front();
179+
Stack const& output = visitFunctionCall(_call);
180+
yulAssert(output.size() == 1, "");
181+
return output.front();
182182
}
183183

184184
void ControlFlowGraphBuilder::operator()(VariableDeclaration const& _varDecl)
@@ -219,8 +219,8 @@ void ControlFlowGraphBuilder::operator()(ExpressionStatement const& _exprStmt)
219219
yulAssert(m_currentBlock, "");
220220
std::visit(util::GenericVisitor{
221221
[&](FunctionCall const& _call) {
222-
CFG::Operation const& operation = visitFunctionCall(_call);
223-
yulAssert(operation.output.empty(), "");
222+
Stack const& output = visitFunctionCall(_call);
223+
yulAssert(output.empty(), "");
224224
},
225225
[&](auto const&) { yulAssert(false, ""); }
226226
}, _exprStmt.expression);
@@ -239,6 +239,9 @@ void ControlFlowGraphBuilder::operator()(ExpressionStatement const& _exprStmt)
239239
void ControlFlowGraphBuilder::operator()(Block const& _block)
240240
{
241241
ScopedSaveAndRestore saveScope(m_scope, m_info.scopes.at(&_block).get());
242+
for (auto const& statement: _block.statements)
243+
if (auto const* function = get_if<FunctionDefinition>(&statement))
244+
registerFunction(*function);
242245
for (auto const& statement: _block.statements)
243246
std::visit(*this, statement);
244247
}
@@ -386,11 +389,26 @@ void ControlFlowGraphBuilder::operator()(FunctionDefinition const& _function)
386389
Scope::Function& function = std::get<Scope::Function>(m_scope->identifiers.at(_function.name));
387390
m_graph.functions.emplace_back(&function);
388391

392+
CFG::FunctionInfo& functionInfo = m_graph.functionInfo.at(&function);
393+
394+
ControlFlowGraphBuilder builder{m_graph, m_info, m_dialect};
395+
builder.m_currentFunction = &functionInfo;
396+
builder.m_currentBlock = functionInfo.entry;
397+
builder(_function.body);
398+
builder.m_currentBlock->exit = CFG::BasicBlock::FunctionReturn{debugDataOf(_function), &functionInfo};
399+
}
400+
401+
void ControlFlowGraphBuilder::registerFunction(FunctionDefinition const& _function)
402+
{
403+
yulAssert(m_scope, "");
404+
yulAssert(m_scope->identifiers.count(_function.name), "");
405+
Scope::Function& function = std::get<Scope::Function>(m_scope->identifiers.at(_function.name));
406+
389407
yulAssert(m_info.scopes.at(&_function.body), "");
390408
Scope* virtualFunctionScope = m_info.scopes.at(m_info.virtualBlocks.at(&_function).get()).get();
391409
yulAssert(virtualFunctionScope, "");
392410

393-
auto&& [it, inserted] = m_graph.functionInfo.emplace(std::make_pair(&function, CFG::FunctionInfo{
411+
bool inserted = m_graph.functionInfo.emplace(std::make_pair(&function, CFG::FunctionInfo{
394412
_function.debugData,
395413
function,
396414
&m_graph.makeBlock(debugDataOf(_function.body)),
@@ -406,19 +424,11 @@ void ControlFlowGraphBuilder::operator()(FunctionDefinition const& _function)
406424
_retVar.debugData
407425
};
408426
}) | ranges::to<vector>
409-
}));
410-
yulAssert(inserted, "");
411-
CFG::FunctionInfo& functionInfo = it->second;
412-
413-
ControlFlowGraphBuilder builder{m_graph, m_info, m_dialect};
414-
builder.m_currentFunction = &functionInfo;
415-
builder.m_currentBlock = functionInfo.entry;
416-
builder(_function.body);
417-
builder.m_currentBlock->exit = CFG::BasicBlock::FunctionReturn{debugDataOf(_function), &functionInfo};
427+
})).second;
428+
yulAssert(inserted);
418429
}
419430

420-
421-
CFG::Operation const& ControlFlowGraphBuilder::visitFunctionCall(FunctionCall const& _call)
431+
Stack const& ControlFlowGraphBuilder::visitFunctionCall(FunctionCall const& _call)
422432
{
423433
yulAssert(m_scope, "");
424434
yulAssert(m_currentBlock, "");
@@ -439,7 +449,7 @@ CFG::Operation const& ControlFlowGraphBuilder::visitFunctionCall(FunctionCall co
439449
}) | ranges::to<Stack>,
440450
// operation
441451
move(builtinCall)
442-
});
452+
}).output;
443453
}
444454
else
445455
{
@@ -456,17 +466,17 @@ CFG::Operation const& ControlFlowGraphBuilder::visitFunctionCall(FunctionCall co
456466
}) | ranges::to<Stack>,
457467
// operation
458468
CFG::FunctionCall{_call.debugData, function, _call}
459-
});
469+
}).output;
460470
}
461471
}
462472

463473
Stack ControlFlowGraphBuilder::visitAssignmentRightHandSide(Expression const& _expression, size_t _expectedSlotCount)
464474
{
465475
return std::visit(util::GenericVisitor{
466476
[&](FunctionCall const& _call) -> Stack {
467-
CFG::Operation const& operation = visitFunctionCall(_call);
468-
yulAssert(_expectedSlotCount == operation.output.size(), "");
469-
return operation.output;
477+
Stack const& output = visitFunctionCall(_call);
478+
yulAssert(_expectedSlotCount == output.size(), "");
479+
return output;
470480
},
471481
[&](auto const& _identifierOrLiteral) -> Stack {
472482
yulAssert(_expectedSlotCount == 1, "");

libyul/backends/evm/ControlFlowGraphBuilder.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ class ControlFlowGraphBuilder
5757
AsmAnalysisInfo const& _analysisInfo,
5858
Dialect const& _dialect
5959
);
60-
CFG::Operation const& visitFunctionCall(FunctionCall const&);
60+
void registerFunction(FunctionDefinition const& _function);
61+
Stack const& visitFunctionCall(FunctionCall const&);
6162
Stack visitAssignmentRightHandSide(Expression const& _expression, size_t _expectedSlotCount);
6263

6364
Scope::Function const& lookupFunction(YulString _name) const;

0 commit comments

Comments
 (0)