Merge pull request #5594 from ethereum/fullInlinerNoHoister

[Yul] Relax dependency of FullInliner on FunctionHoister.
This commit is contained in:
chriseth 2018-12-05 12:25:03 +01:00 committed by GitHub
commit 1e6c368bba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 23 additions and 13 deletions

View File

@ -94,8 +94,11 @@ bool FullInliner::shallInline(FunctionCall const& _funCall, YulString _callSite)
if (_funCall.functionName.name == _callSite) if (_funCall.functionName.name == _callSite)
return false; return false;
FunctionDefinition& calledFunction = function(_funCall.functionName.name); FunctionDefinition* calledFunction = function(_funCall.functionName.name);
if (m_alwaysInline.count(calledFunction.name)) if (!calledFunction)
return false;
if (m_alwaysInline.count(calledFunction->name))
return true; return true;
// Constant arguments might provide a means for further optimization, so they cause a bonus. // Constant arguments might provide a means for further optimization, so they cause a bonus.
@ -110,7 +113,7 @@ bool FullInliner::shallInline(FunctionCall const& _funCall, YulString _callSite)
break; break;
} }
size_t size = m_functionSizes.at(calledFunction.name); size_t size = m_functionSizes.at(calledFunction->name);
return (size < 10 || (constantArg && size < 50)); return (size < 10 || (constantArg && size < 50));
} }
@ -149,12 +152,13 @@ vector<Statement> InlineModifier::performInline(Statement& _statement, FunctionC
vector<Statement> newStatements; vector<Statement> newStatements;
map<YulString, YulString> variableReplacements; map<YulString, YulString> variableReplacements;
FunctionDefinition& function = m_driver.function(_funCall.functionName.name); FunctionDefinition* function = m_driver.function(_funCall.functionName.name);
assertThrow(!!function, OptimizerException, "Attempt to inline invalid function.");
// helper function to create a new variable that is supposed to model // helper function to create a new variable that is supposed to model
// an existing variable. // an existing variable.
auto newVariable = [&](TypedName const& _existingVariable, Expression* _value) { auto newVariable = [&](TypedName const& _existingVariable, Expression* _value) {
YulString newName = m_nameDispenser.newName(_existingVariable.name, function.name); YulString newName = m_nameDispenser.newName(_existingVariable.name, function->name);
variableReplacements[_existingVariable.name] = newName; variableReplacements[_existingVariable.name] = newName;
VariableDeclaration varDecl{_funCall.location, {{_funCall.location, newName, _existingVariable.type}}, {}}; VariableDeclaration varDecl{_funCall.location, {{_funCall.location, newName, _existingVariable.type}}, {}};
if (_value) if (_value)
@ -163,11 +167,11 @@ vector<Statement> InlineModifier::performInline(Statement& _statement, FunctionC
}; };
for (size_t i = 0; i < _funCall.arguments.size(); ++i) for (size_t i = 0; i < _funCall.arguments.size(); ++i)
newVariable(function.parameters[i], &_funCall.arguments[i]); newVariable(function->parameters[i], &_funCall.arguments[i]);
for (auto const& var: function.returnVariables) for (auto const& var: function->returnVariables)
newVariable(var, nullptr); newVariable(var, nullptr);
Statement newBody = BodyCopier(m_nameDispenser, function.name, variableReplacements)(function.body); Statement newBody = BodyCopier(m_nameDispenser, function->name, variableReplacements)(function->body);
newStatements += std::move(boost::get<Block>(newBody).statements); newStatements += std::move(boost::get<Block>(newBody).statements);
boost::apply_visitor(GenericFallbackVisitor<Assignment, VariableDeclaration>{ boost::apply_visitor(GenericFallbackVisitor<Assignment, VariableDeclaration>{
@ -179,7 +183,7 @@ vector<Statement> InlineModifier::performInline(Statement& _statement, FunctionC
{_assignment.variableNames[i]}, {_assignment.variableNames[i]},
make_shared<Expression>(Identifier{ make_shared<Expression>(Identifier{
_assignment.location, _assignment.location,
variableReplacements.at(function.returnVariables[i].name) variableReplacements.at(function->returnVariables[i].name)
}) })
}); });
}, },
@ -191,7 +195,7 @@ vector<Statement> InlineModifier::performInline(Statement& _statement, FunctionC
{std::move(_varDecl.variables[i])}, {std::move(_varDecl.variables[i])},
make_shared<Expression>(Identifier{ make_shared<Expression>(Identifier{
_varDecl.location, _varDecl.location,
variableReplacements.at(function.returnVariables[i].name) variableReplacements.at(function->returnVariables[i].name)
}) })
}); });
} }

View File

@ -63,8 +63,8 @@ class NameCollector;
* code of f, with replacements: a -> f_a, b -> f_b, c -> f_c * code of f, with replacements: a -> f_a, b -> f_b, c -> f_c
* let z := f_c * let z := f_c
* *
* Prerequisites: Disambiguator, Function Hoister * Prerequisites: Disambiguator
* More efficient if run after: Expression Splitter * More efficient if run after: Function Hoister, Expression Splitter
*/ */
class FullInliner: public ASTModifier class FullInliner: public ASTModifier
{ {
@ -77,7 +77,13 @@ public:
/// @param _callSite the name of the function in which the function call is located. /// @param _callSite the name of the function in which the function call is located.
bool shallInline(FunctionCall const& _funCall, YulString _callSite); bool shallInline(FunctionCall const& _funCall, YulString _callSite);
FunctionDefinition& function(YulString _name) { return *m_functions.at(_name); } FunctionDefinition* function(YulString _name)
{
auto it = m_functions.find(_name);
if (it != m_functions.end())
return it->second;
return nullptr;
}
private: private:
void updateCodeSize(FunctionDefinition& fun); void updateCodeSize(FunctionDefinition& fun);