Do not inline into already big functions.

This commit is contained in:
chriseth
2018-12-13 12:12:54 +01:00
parent 642c69f935
commit 60a368244a
8 changed files with 290 additions and 174 deletions
+16 -3
View File
@@ -49,6 +49,8 @@ FullInliner::FullInliner(Block& _ast, NameDispenser& _dispenser):
if (ssaValue.second && ssaValue.second->type() == typeid(Literal))
m_constants.emplace(ssaValue.first);
// Store size of global statements.
m_functionSizes[YulString{}] = CodeSize::codeSize(_ast);
map<YulString, size_t> references = ReferencesCounter::countReferences(m_ast);
for (auto& statement: m_ast.statements)
{
@@ -58,7 +60,7 @@ FullInliner::FullInliner(Block& _ast, NameDispenser& _dispenser):
m_functions[fun.name] = &fun;
// Always inline functions that are only called once.
if (references[fun.name] == 1)
m_alwaysInline.emplace(fun.name);
m_singleUse.emplace(fun.name);
updateCodeSize(fun);
}
}
@@ -98,7 +100,11 @@ bool FullInliner::shallInline(FunctionCall const& _funCall, YulString _callSite)
if (!calledFunction)
return false;
if (m_alwaysInline.count(calledFunction->name))
// Do not inline into already big functions.
if (m_functionSizes.at(_callSite) > 100)
return false;
if (m_singleUse.count(calledFunction->name))
return true;
// Constant arguments might provide a means for further optimization, so they cause a bonus.
@@ -114,7 +120,12 @@ bool FullInliner::shallInline(FunctionCall const& _funCall, YulString _callSite)
}
size_t size = m_functionSizes.at(calledFunction->name);
return (size < 10 || (constantArg && size < 50));
return (size < 10 || (constantArg && size < 30));
}
void FullInliner::tentativelyUpdateCodeSize(YulString _function, YulString _callSite)
{
m_functionSizes.at(_callSite) += m_functionSizes.at(_function);
}
@@ -155,6 +166,8 @@ vector<Statement> InlineModifier::performInline(Statement& _statement, FunctionC
FunctionDefinition* function = m_driver.function(_funCall.functionName.name);
assertThrow(!!function, OptimizerException, "Attempt to inline invalid function.");
m_driver.tentativelyUpdateCodeSize(function->name, m_currentFunction);
// helper function to create a new variable that is supposed to model
// an existing variable.
auto newVariable = [&](TypedName const& _existingVariable, Expression* _value) {