mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #5205 from ethereum/cseAlsoSubstituteVariables
[Yul] Also substitute variables in Common Subexpression Eliminator
This commit is contained in:
commit
6f595ee0df
@ -33,9 +33,31 @@ using namespace dev::julia;
|
||||
|
||||
void CommonSubexpressionEliminator::visit(Expression& _e)
|
||||
{
|
||||
// Single exception for substitution: We do not substitute one variable for another.
|
||||
if (_e.type() != typeid(Identifier))
|
||||
// TODO this search rather inefficient.
|
||||
// We visit the inner expression first to first simplify inner expressions,
|
||||
// which hopefully allows more matches.
|
||||
// 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)
|
||||
{
|
||||
assertThrow(var.second, OptimizerException, "");
|
||||
@ -45,5 +67,5 @@ void CommonSubexpressionEliminator::visit(Expression& _e)
|
||||
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
|
||||
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
|
||||
|
||||
## 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