mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Also substitute variables in CSE.
This commit is contained in:
parent
26dc876c28
commit
7940dafd0d
@ -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);
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
// }
|
Loading…
Reference in New Issue
Block a user