aboutsummaryrefslogtreecommitdiffstats
path: root/libyul/optimiser/CommonSubexpressionEliminator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libyul/optimiser/CommonSubexpressionEliminator.cpp')
-rw-r--r--libyul/optimiser/CommonSubexpressionEliminator.cpp17
1 files changed, 15 insertions, 2 deletions
diff --git a/libyul/optimiser/CommonSubexpressionEliminator.cpp b/libyul/optimiser/CommonSubexpressionEliminator.cpp
index 9b851333..5f182eba 100644
--- a/libyul/optimiser/CommonSubexpressionEliminator.cpp
+++ b/libyul/optimiser/CommonSubexpressionEliminator.cpp
@@ -25,6 +25,7 @@
#include <libyul/optimiser/SyntacticalEquality.h>
#include <libyul/Exceptions.h>
#include <libyul/AsmData.h>
+#include <libyul/Dialect.h>
using namespace std;
using namespace dev;
@@ -32,12 +33,24 @@ using namespace yul;
void CommonSubexpressionEliminator::visit(Expression& _e)
{
+ bool descend = true;
+ // If this is a function call to a function that requires literal arguments,
+ // do not try to simplify there.
+ if (_e.type() == typeid(FunctionCall))
+ if (BuiltinFunction const* builtin = m_dialect.builtin(boost::get<FunctionCall>(_e).functionName.name))
+ if (builtin->literalArguments)
+ // We should not modify function arguments that have to be literals
+ // Note that replacing the function call entirely is fine,
+ // if the function call is movable.
+ descend = false;
+
// 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 (descend)
+ DataFlowAnalyzer::visit(_e);
if (_e.type() == typeid(Identifier))
{
@@ -61,7 +74,7 @@ void CommonSubexpressionEliminator::visit(Expression& _e)
{
assertThrow(var.second, OptimizerException, "");
assertThrow(inScope(var.first), OptimizerException, "");
- if (SyntacticalEqualityChecker::equal(_e, *var.second))
+ if (SyntacticallyEqual{}(_e, *var.second))
{
_e = Identifier{locationOf(_e), var.first};
break;