From 4370bf5c40ed1942c2dec38bad67e0b10f3d84c7 Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 17 Jan 2018 16:38:06 +0100 Subject: Inline functions returning nothing. --- libjulia/optimiser/FullInliner.cpp | 32 ++++++++++++++++++++++---------- libjulia/optimiser/FullInliner.h | 3 +++ 2 files changed, 25 insertions(+), 10 deletions(-) (limited to 'libjulia/optimiser') diff --git a/libjulia/optimiser/FullInliner.cpp b/libjulia/optimiser/FullInliner.cpp index f5721617..42cbc804 100644 --- a/libjulia/optimiser/FullInliner.cpp +++ b/libjulia/optimiser/FullInliner.cpp @@ -119,7 +119,7 @@ void InlineModifier::visit(Expression& _expression) // TODO: Insert good heuristic here. Perhaps implement that inside the driver. bool doInline = funCall.functionName.name != m_currentFunction; - if (fun.returnVariables.size() != 1) + if (fun.returnVariables.size() > 1) doInline = false; { @@ -137,18 +137,23 @@ void InlineModifier::visit(Expression& _expression) return; map variableReplacements; - string returnVariable = fun.returnVariables[0].name; for (size_t i = 0; i < funCall.arguments.size(); ++i) variableReplacements[fun.parameters[i].name] = boost::get(funCall.arguments[i]).name; - variableReplacements[returnVariable] = newName(fun.name + "_" + returnVariable); - - m_statementsToPrefix.emplace_back(VariableDeclaration{ - funCall.location, - {{funCall.location, variableReplacements[returnVariable], fun.returnVariables[0].type}}, - {} - }); + if (fun.returnVariables.empty()) + _expression = noop(funCall.location); + else + { + string returnVariable = fun.returnVariables[0].name; + variableReplacements[returnVariable] = newName(fun.name + "_" + returnVariable); + + m_statementsToPrefix.emplace_back(VariableDeclaration{ + funCall.location, + {{funCall.location, variableReplacements[returnVariable], fun.returnVariables[0].type}}, + {} + }); + _expression = Identifier{funCall.location, variableReplacements[returnVariable]}; + } m_statementsToPrefix.emplace_back(BodyCopier(m_nameDispenser, fun.name + "_", variableReplacements)(fun.body)); - _expression = Identifier{funCall.location, variableReplacements[returnVariable]}; } void InlineModifier::visitArguments( @@ -202,6 +207,13 @@ string InlineModifier::newName(string const& _prefix) return m_nameDispenser.newName(_prefix); } +Expression InlineModifier::noop(SourceLocation const& _location) +{ + return FunctionalInstruction{_location, solidity::Instruction::POP, { + Literal{_location, assembly::LiteralKind::Number, "0", ""} + }}; +} + Statement BodyCopier::operator()(VariableDeclaration const& _varDecl) { for (auto const& var: _varDecl.variables) diff --git a/libjulia/optimiser/FullInliner.h b/libjulia/optimiser/FullInliner.h index e9a7e4fc..21998452 100644 --- a/libjulia/optimiser/FullInliner.h +++ b/libjulia/optimiser/FullInliner.h @@ -137,6 +137,9 @@ private: std::string newName(std::string const& _prefix); + /// @returns an expression returning nothing. + Expression noop(SourceLocation const& _location); + /// List of statements that should go in front of the currently visited AST element, /// at the statement level. std::vector m_statementsToPrefix; -- cgit