Also substitute variables in CSE.

This commit is contained in:
chriseth 2018-10-11 19:58:09 +02:00
parent 26dc876c28
commit 7940dafd0d
3 changed files with 67 additions and 4 deletions

View File

@ -33,9 +33,31 @@ using namespace dev::julia;
void CommonSubexpressionEliminator::visit(Expression& _e) void CommonSubexpressionEliminator::visit(Expression& _e)
{ {
// Single exception for substitution: We do not substitute one variable for another. // We visit the inner expression first to first simplify inner expressions,
if (_e.type() != typeid(Identifier)) // which hopefully allows more matches.
// TODO this search rather inefficient. // Note that the DataFlowAnalyzer itself only has code for visiting Statements,
// so this basically invokes the AST walker directly and thus post-visiting
// is also fine with regards to data flow analysis.
DataFlowAnalyzer::visit(_e);
if (_e.type() == typeid(Identifier))
{
Identifier& identifier = boost::get<Identifier>(_e);
string const& name = identifier.name;
if (m_value.count(name))
{
assertThrow(m_value.at(name), OptimizerException, "");
if (m_value.at(name)->type() == typeid(Identifier))
{
string const& value = boost::get<Identifier>(*m_value.at(name)).name;
if (inScope(value))
_e = Identifier{locationOf(_e), value};
}
}
}
else
{
// TODO this search is rather inefficient.
for (auto const& var: m_value) for (auto const& var: m_value)
{ {
assertThrow(var.second, OptimizerException, ""); assertThrow(var.second, OptimizerException, "");
@ -45,5 +67,5 @@ void CommonSubexpressionEliminator::visit(Expression& _e)
break; break;
} }
} }
DataFlowAnalyzer::visit(_e); }
} }

View File

@ -97,6 +97,20 @@ of any function call or opcode execution, the transformation is not performed.
Note that the component will not move the assigned value of a variable assignment Note that the component will not move the assigned value of a variable assignment
or a variable that is referenced more than once. or a variable that is referenced more than once.
## Common Subexpression Eliminator
This step replaces a subexpression by the value of a pre-existing variable
that currently has the same value (only if the value is movable), based
on a syntactic comparison.
This can be used to compute a local value numbering, especially if the
expression splitter is used before.
The expression simplifier will be able to perform better replacements
if the common subexpression eliminator was run right before it.
Prerequisites: Disambiguator
## Full Function Inliner ## Full Function Inliner
## Rematerialisation ## Rematerialisation

View File

@ -0,0 +1,27 @@
{
let a := mload(0)
let b := add(a, 7)
let c := a
let d := c
let x := add(a, b)
// CSE has to recognize equality with x here.
let y := add(d, add(c, 7))
// some reassignments
b := mload(a)
a := b
mstore(2, a)
}
// ----
// commonSubexpressionEliminator
// {
// let a := mload(0)
// let b := add(a, 7)
// let c := a
// let d := a
// let x := add(a, b)
// let y := x
// b := mload(a)
// a := b
// mstore(2, b)
// }