aboutsummaryrefslogtreecommitdiffstats
path: root/libjulia/optimiser/Rematerialiser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libjulia/optimiser/Rematerialiser.cpp')
-rw-r--r--libjulia/optimiser/Rematerialiser.cpp159
1 files changed, 9 insertions, 150 deletions
diff --git a/libjulia/optimiser/Rematerialiser.cpp b/libjulia/optimiser/Rematerialiser.cpp
index bf7d7d16..eaa75e33 100644
--- a/libjulia/optimiser/Rematerialiser.cpp
+++ b/libjulia/optimiser/Rematerialiser.cpp
@@ -20,176 +20,35 @@
#include <libjulia/optimiser/Rematerialiser.h>
+#include <libjulia/optimiser/Metrics.h>
#include <libjulia/optimiser/ASTCopier.h>
-#include <libjulia/optimiser/NameCollector.h>
#include <libsolidity/inlineasm/AsmData.h>
-#include <libjulia/optimiser/Semantics.h>
-
-#include <libdevcore/CommonData.h>
-
-#include <boost/range/adaptor/reversed.hpp>
-
using namespace std;
using namespace dev;
using namespace dev::julia;
-void Rematerialiser::operator()(Assignment& _assignment)
-{
- set<string> names;
- for (auto const& var: _assignment.variableNames)
- names.insert(var.name);
- handleAssignment(names, _assignment.value.get());
-}
-
-void Rematerialiser::operator()(VariableDeclaration& _varDecl)
-{
- set<string> names;
- for (auto const& var: _varDecl.variables)
- names.insert(var.name);
- m_variableScopes.back().first += names;
- handleAssignment(names, _varDecl.value.get());
-}
-
-void Rematerialiser::operator()(If& _if)
-{
- ASTModifier::operator()(_if);
-
- Assignments ass;
- ass(_if.body);
- handleAssignment(ass.names(), nullptr);
-}
-
-void Rematerialiser::operator()(Switch& _switch)
-{
- boost::apply_visitor(*this, *_switch.expression);
- set<string> assignedVariables;
- for (auto& _case: _switch.cases)
- {
- (*this)(_case.body);
- Assignments ass;
- ass(_case.body);
- assignedVariables += ass.names();
- // This is a little too destructive, we could retain the old replacements.
- handleAssignment(ass.names(), nullptr);
- }
- handleAssignment(assignedVariables, nullptr);
-}
-
-void Rematerialiser::operator()(FunctionDefinition& _fun)
-{
- m_variableScopes.push_back(make_pair(set<string>(), true));
- for (auto const& parameter: _fun.parameters)
- m_variableScopes.back().first.insert(parameter.name);
- for (auto const& var: _fun.returnVariables)
- m_variableScopes.back().first.insert(var.name);
- ASTModifier::operator()(_fun);
- m_variableScopes.pop_back();
-}
-
-void Rematerialiser::operator()(ForLoop& _for)
-{
- // Special scope handling of the pre block.
- m_variableScopes.push_back(make_pair(set<string>(), false));
- for (auto& statement: _for.pre.statements)
- visit(statement);
-
- Assignments ass;
- ass(_for.body);
- ass(_for.post);
- handleAssignment(ass.names(), nullptr);
-
- visit(*_for.condition);
- (*this)(_for.body);
- (*this)(_for.post);
-
- handleAssignment(ass.names(), nullptr);
-
- m_variableScopes.pop_back();
-}
-
-void Rematerialiser::operator()(Block& _block)
-{
- size_t numScopes = m_variableScopes.size();
- m_variableScopes.push_back(make_pair(set<string>(), false));
- ASTModifier::operator()(_block);
- m_variableScopes.pop_back();
- solAssert(numScopes == m_variableScopes.size(), "");
-}
-
-void Rematerialiser::handleAssignment(set<string> const& _variables, Expression* _value)
-{
- MovableChecker movableChecker;
- if (_value)
- {
- visit(*_value);
- movableChecker.visit(*_value);
- }
- if (_variables.size() == 1)
- {
- string const& name = *_variables.begin();
- if (movableChecker.movable() && _value)
- // TODO Plus heuristic about size of value
- // TODO If _value is null, we could use zero.
- m_substitutions[name] = _value;
- else
- m_substitutions.erase(name);
- }
- else
- for (auto const& name: _variables)
- m_substitutions.erase(name);
-
- // Disallow substitutions that use a variable that will be reassigned by this assignment.
- for (auto const& name: _variables)
- for (auto const& ref: m_referencedBy[name])
- m_substitutions.erase(ref);
- // Update the fact which variables are referenced by the newly assigned variables
- for (auto const& name: _variables)
- {
- for (auto const& ref: m_references[name])
- m_referencedBy[ref].erase(name);
- m_references[name].clear();
- }
- auto const& referencedVariables = movableChecker.referencedVariables();
- for (auto const& name: _variables)
- {
- m_references[name] = referencedVariables;
- for (auto const& ref: referencedVariables)
- m_referencedBy[ref].insert(name);
- }
-}
-
-bool Rematerialiser::inScope(string const& _variableName) const
-{
- for (auto const& scope: m_variableScopes | boost::adaptors::reversed)
- {
- if (scope.first.count(_variableName))
- return true;
- if (scope.second)
- return false;
- }
- return false;
-}
-
void Rematerialiser::visit(Expression& _e)
{
if (_e.type() == typeid(Identifier))
{
Identifier& identifier = boost::get<Identifier>(_e);
- if (m_substitutions.count(identifier.name))
+ if (m_value.count(identifier.name))
{
string name = identifier.name;
- bool doSubstitute = true;
+ bool expressionValid = true;
for (auto const& ref: m_references[name])
if (!inScope(ref))
{
- doSubstitute = false;
+ expressionValid = false;
break;
}
- if (doSubstitute)
- _e = (ASTCopier{}).translate(*m_substitutions.at(name));
+ solAssert(m_value.at(name), "");
+ auto const& value = *m_value.at(name);
+ if (expressionValid && CodeSize::codeSize(value) <= 7)
+ _e = (ASTCopier{}).translate(value);
}
}
- ASTModifier::visit(_e);
+ DataFlowAnalyzer::visit(_e);
}