mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Use builtin iszero for for loop condition rewriting.
This commit is contained in:
committed by
Daniel Kirchner
parent
324cc71b13
commit
4f80117eef
@@ -61,6 +61,7 @@ struct Dialect: boost::noncopyable
|
||||
|
||||
virtual BuiltinFunction const* discardFunction() const { return nullptr; }
|
||||
virtual BuiltinFunction const* equalityFunction() const { return nullptr; }
|
||||
virtual BuiltinFunction const* booleanNegationFunction() const { return nullptr; }
|
||||
|
||||
virtual std::set<YulString> fixedFunctionNames() const { return {}; }
|
||||
|
||||
|
||||
@@ -70,6 +70,7 @@ struct EVMDialect: public Dialect
|
||||
|
||||
BuiltinFunctionForEVM const* discardFunction() const override { return builtin("pop"_yulstring); }
|
||||
BuiltinFunctionForEVM const* equalityFunction() const override { return builtin("eq"_yulstring); }
|
||||
BuiltinFunctionForEVM const* booleanNegationFunction() const override { return builtin("iszero"_yulstring); }
|
||||
|
||||
static EVMDialect const& looseAssemblyForEVM(langutil::EVMVersion _version);
|
||||
static EVMDialect const& strictAssemblyForEVM(langutil::EVMVersion _version);
|
||||
|
||||
@@ -47,6 +47,7 @@ struct WasmDialect: public Dialect
|
||||
BuiltinFunction const* builtin(YulString _name) const override;
|
||||
BuiltinFunction const* discardFunction() const override { return builtin("drop"_yulstring); }
|
||||
BuiltinFunction const* equalityFunction() const override { return builtin("i64.eq"_yulstring); }
|
||||
BuiltinFunction const* booleanNegationFunction() const override { return builtin("i64.eqz"_yulstring); }
|
||||
|
||||
std::set<YulString> fixedFunctionNames() const override { return {"main"_yulstring}; }
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ using namespace yul;
|
||||
|
||||
void ForLoopConditionIntoBody::operator()(ForLoop& _forLoop)
|
||||
{
|
||||
if (_forLoop.condition->type() != typeid(Literal))
|
||||
if (m_dialect.booleanNegationFunction() && _forLoop.condition->type() != typeid(Literal))
|
||||
{
|
||||
langutil::SourceLocation loc = locationOf(*_forLoop.condition);
|
||||
_forLoop.body.statements.insert(
|
||||
@@ -33,9 +33,9 @@ void ForLoopConditionIntoBody::operator()(ForLoop& _forLoop)
|
||||
If {
|
||||
loc,
|
||||
make_unique<Expression>(
|
||||
FunctionalInstruction {
|
||||
FunctionCall {
|
||||
loc,
|
||||
eth::Instruction::ISZERO,
|
||||
{loc, m_dialect.booleanNegationFunction()->name},
|
||||
make_vector<Expression>(std::move(*_forLoop.condition))
|
||||
}
|
||||
),
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <libyul/optimiser/ASTWalker.h>
|
||||
#include <libyul/Dialect.h>
|
||||
|
||||
namespace yul
|
||||
{
|
||||
@@ -29,17 +30,22 @@ namespace yul
|
||||
* By moving the iteration check part into the ForLoop body, we can apply expression splitter
|
||||
* to the condition expression.
|
||||
*
|
||||
* This rewritter will skip loops that already have literal constant as iteration condition.
|
||||
* This rewriter will skip loops that already have literal constant as iteration condition.
|
||||
*
|
||||
* Requirements:
|
||||
* - The Disambiguator must be run upfront.
|
||||
* - To avoid unnecessary rewrite, it is recommended to run this rewriter after StructuralSimplifier.
|
||||
* - Only works for dialects with a builtin boolean negation function.
|
||||
*/
|
||||
class ForLoopConditionIntoBody: public ASTModifier
|
||||
{
|
||||
public:
|
||||
ForLoopConditionIntoBody(Dialect const& _dialect): m_dialect(_dialect) {}
|
||||
using ASTModifier::operator();
|
||||
void operator()(ForLoop& _forLoop) override;
|
||||
|
||||
private:
|
||||
Dialect const& m_dialect;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <libyul/optimiser/ExpressionJoiner.h>
|
||||
#include <libyul/optimiser/ExpressionInliner.h>
|
||||
#include <libyul/optimiser/FullInliner.h>
|
||||
#include <libyul/optimiser/ForLoopConditionIntoBody.h>
|
||||
#include <libyul/optimiser/ForLoopInitRewriter.h>
|
||||
#include <libyul/optimiser/Rematerialiser.h>
|
||||
#include <libyul/optimiser/UnusedPruner.h>
|
||||
@@ -94,6 +95,7 @@ void OptimiserSuite::run(
|
||||
LiteralRematerialiser{_dialect}(ast);
|
||||
StructuralSimplifier{}(ast);
|
||||
ControlFlowSimplifier{_dialect}(ast);
|
||||
ForLoopConditionIntoBody{_dialect}(ast);
|
||||
BlockFlattener{}(ast);
|
||||
|
||||
// None of the above can make stack problems worse.
|
||||
|
||||
Reference in New Issue
Block a user