aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2018-01-17 23:38:06 +0800
committerchriseth <chris@ethereum.org>2018-05-02 23:39:42 +0800
commit4370bf5c40ed1942c2dec38bad67e0b10f3d84c7 (patch)
tree8858957cb9d3795dc6b590182401da426c814cd7
parent5cd84a630c2005a4b971130840bb7361560fd120 (diff)
downloaddexon-solidity-4370bf5c40ed1942c2dec38bad67e0b10f3d84c7.tar.gz
dexon-solidity-4370bf5c40ed1942c2dec38bad67e0b10f3d84c7.tar.zst
dexon-solidity-4370bf5c40ed1942c2dec38bad67e0b10f3d84c7.zip
Inline functions returning nothing.
-rw-r--r--libjulia/optimiser/FullInliner.cpp32
-rw-r--r--libjulia/optimiser/FullInliner.h3
2 files changed, 25 insertions, 10 deletions
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<string, string> variableReplacements;
- string returnVariable = fun.returnVariables[0].name;
for (size_t i = 0; i < funCall.arguments.size(); ++i)
variableReplacements[fun.parameters[i].name] = boost::get<Identifier>(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<Statement> m_statementsToPrefix;