From d233c66795db85e37a967ec38de3b31be2b5105f Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Wed, 10 Aug 2022 15:48:06 +0200 Subject: [PATCH 1/9] Special case code generation for for loops. --- Changelog.md | 1 + libsolidity/analysis/PostTypeChecker.cpp | 78 +++++++++++++++++-- libsolidity/analysis/PostTypeChecker.h | 3 + libsolidity/ast/ASTAnnotations.h | 1 + libsolidity/ast/ASTJsonExporter.cpp | 18 +++-- libsolidity/codegen/ContractCompiler.cpp | 9 +++ .../codegen/ir/IRGeneratorForStatements.cpp | 13 +++- .../codegen/ir/IRGeneratorForStatements.h | 3 +- 8 files changed, 111 insertions(+), 15 deletions(-) diff --git a/Changelog.md b/Changelog.md index 5fdd6b78e..aa80aaede 100644 --- a/Changelog.md +++ b/Changelog.md @@ -30,6 +30,7 @@ Language Features: Compiler Features: + * Code Generator: Remove redundant overflow checks in specific for loops. * Commandline Interface: Add ``--ast-compact-json`` output in assembler mode. * Commandline Interface: Add ``--ir-ast-json`` and ``--ir-optimized-ast-json`` outputs for Solidity input, providing AST in compact JSON format for IR and optimized IR. * Commandline Interface: Respect ``--optimize-yul`` and ``--no-optimize-yul`` in compiler mode and accept them in assembler mode as well. ``--optimize --no-optimize-yul`` combination now allows enabling EVM assembly optimizer without enabling Yul optimizer. diff --git a/libsolidity/analysis/PostTypeChecker.cpp b/libsolidity/analysis/PostTypeChecker.cpp index bc9df3dc4..b68167c1d 100644 --- a/libsolidity/analysis/PostTypeChecker.cpp +++ b/libsolidity/analysis/PostTypeChecker.cpp @@ -129,6 +129,17 @@ void PostTypeChecker::endVisit(ModifierInvocation const& _modifierInvocation) callEndVisit(_modifierInvocation); } + +bool PostTypeChecker::visit(ForStatement const& _forStatement) +{ + return callVisit(_forStatement); +} + +void PostTypeChecker::endVisit(ForStatement const& _forStatement) +{ + callEndVisit(_forStatement); +} + namespace { struct ConstStateVarCircularReferenceChecker: public PostTypeChecker::Checker @@ -421,15 +432,70 @@ struct ReservedErrorSelector: public PostTypeChecker::Checker } }; +class LValueChecker: public ASTConstVisitor +{ +public: + LValueChecker(Identifier const& _identifier): m_declaration(_identifier.annotation().referencedDeclaration) {} + bool willBeWrittenTo() const { return m_willBeWrittenTo; } + void endVisit(Identifier const& _identifier) override + { + if ( + _identifier.annotation().referencedDeclaration == m_declaration && + _identifier.annotation().willBeWrittenTo + ) + m_willBeWrittenTo = true; + } +private: + Declaration const* m_declaration; + bool m_willBeWrittenTo = false; +}; + +struct SimpleCounterForLoopChecker: public PostTypeChecker::Checker +{ + SimpleCounterForLoopChecker(ErrorReporter& _errorReporter): Checker(_errorReporter) {} + bool visit(ForStatement const& _forStatement) override + { + _forStatement.annotation().isSimpleCounterLoop = isSimpleCounterLoop(_forStatement); + return true; + } + bool isSimpleCounterLoop(ForStatement const& _forStatement) const + { + auto const* cond = dynamic_cast(_forStatement.condition()); + if (!cond || cond->getOperator() != Token::LessThan || cond->userDefinedFunctionType()) + return false; + if (!_forStatement.loopExpression()) + return false; + + auto const* post = dynamic_cast(&_forStatement.loopExpression()->expression()); + // This matches both operators ++i and i++ + if (!post || post->getOperator() != Token::Inc || post->userDefinedFunctionType()) + return false; + + auto const* lhsIdentifier = dynamic_cast(&cond->leftExpression()); + auto const* lhsType = dynamic_cast(cond->leftExpression().annotation().type); + auto const *commonType = dynamic_cast(cond->annotation().commonType); + + if (lhsIdentifier && lhsType && commonType && *lhsType == *commonType) + { + LValueChecker lValueChecker{*lhsIdentifier}; + _forStatement.body().accept(lValueChecker); + if (!lValueChecker.willBeWrittenTo()) + return true; + } + return false; + } +}; + } PostTypeChecker::PostTypeChecker(langutil::ErrorReporter& _errorReporter): m_errorReporter(_errorReporter) { - m_checkers.push_back(std::make_shared(_errorReporter)); - m_checkers.push_back(std::make_shared(_errorReporter)); - m_checkers.push_back(std::make_shared(_errorReporter)); - m_checkers.push_back(std::make_shared(_errorReporter)); - m_checkers.push_back(std::make_shared(_errorReporter)); - m_checkers.push_back(std::make_shared(_errorReporter)); + m_checkers.push_back(make_shared(_errorReporter)); + m_checkers.push_back(make_shared(_errorReporter)); + m_checkers.push_back(make_shared(_errorReporter)); + m_checkers.push_back(make_shared(_errorReporter)); + m_checkers.push_back(make_shared(_errorReporter)); + m_checkers.push_back(make_shared(_errorReporter)); + m_checkers.push_back(make_shared(_errorReporter)); } diff --git a/libsolidity/analysis/PostTypeChecker.h b/libsolidity/analysis/PostTypeChecker.h index 04b4fbe7a..178130a35 100644 --- a/libsolidity/analysis/PostTypeChecker.h +++ b/libsolidity/analysis/PostTypeChecker.h @@ -97,6 +97,9 @@ private: bool visit(ModifierInvocation const& _modifierInvocation) override; void endVisit(ModifierInvocation const& _modifierInvocation) override; + bool visit(ForStatement const& _forStatement) override; + void endVisit(ForStatement const& _forStatement) override; + template bool callVisit(T const& _node) { diff --git a/libsolidity/ast/ASTAnnotations.h b/libsolidity/ast/ASTAnnotations.h index 2573015c2..9a1990711 100644 --- a/libsolidity/ast/ASTAnnotations.h +++ b/libsolidity/ast/ASTAnnotations.h @@ -238,6 +238,7 @@ struct TryCatchClauseAnnotation: ASTAnnotation, ScopableAnnotation struct ForStatementAnnotation: StatementAnnotation, ScopableAnnotation { + util::SetOnce isSimpleCounterLoop; }; struct ReturnAnnotation: StatementAnnotation diff --git a/libsolidity/ast/ASTJsonExporter.cpp b/libsolidity/ast/ASTJsonExporter.cpp index b15917809..251622195 100644 --- a/libsolidity/ast/ASTJsonExporter.cpp +++ b/libsolidity/ast/ASTJsonExporter.cpp @@ -742,12 +742,18 @@ bool ASTJsonExporter::visit(WhileStatement const& _node) bool ASTJsonExporter::visit(ForStatement const& _node) { - setJsonNode(_node, "ForStatement", { - std::make_pair("initializationExpression", toJsonOrNull(_node.initializationExpression())), - std::make_pair("condition", toJsonOrNull(_node.condition())), - std::make_pair("loopExpression", toJsonOrNull(_node.loopExpression())), - std::make_pair("body", toJson(_node.body())) - }); + + std::vector> attributes = { + make_pair("initializationExpression", toJsonOrNull(_node.initializationExpression())), + make_pair("condition", toJsonOrNull(_node.condition())), + make_pair("loopExpression", toJsonOrNull(_node.loopExpression())), + make_pair("body", toJson(_node.body())) + }; + + if (_node.annotation().isSimpleCounterLoop.set()) + attributes.emplace_back(make_pair("isSimpleCounterLoop", *_node.annotation().isSimpleCounterLoop)); + + setJsonNode(_node, "ForStatement", std::move(attributes)); return false; } diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 3dfdf76d8..465c284a6 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -1245,7 +1245,16 @@ bool ContractCompiler::visit(ForStatement const& _forStatement) // for's loop expression if existing if (_forStatement.loopExpression()) + { + Arithmetic previousArithmetic = m_context.arithmetic(); + if ( + *_forStatement.annotation().isSimpleCounterLoop && + m_optimiserSettings == OptimiserSettings::standard() + ) + m_context.setArithmetic(Arithmetic::Wrapping); _forStatement.loopExpression()->accept(*this); + m_context.setArithmetic(previousArithmetic); + } m_context.appendJumpTo(loopStart); diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index c05fffbff..ffcb1409b 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -617,7 +617,9 @@ bool IRGeneratorForStatements::visit(ForStatement const& _forStatement) _forStatement.body(), _forStatement.condition(), _forStatement.initializationExpression(), - _forStatement.loopExpression() + _forStatement.loopExpression(), + false, + *_forStatement.annotation().isSimpleCounterLoop ); return false; @@ -3192,7 +3194,8 @@ void IRGeneratorForStatements::generateLoop( Expression const* _conditionExpression, Statement const* _initExpression, ExpressionStatement const* _loopExpression, - bool _isDoWhile + bool _isDoWhile, + bool _isSimpleCounterLoop ) { std::string firstRun; @@ -3209,7 +3212,13 @@ void IRGeneratorForStatements::generateLoop( _initExpression->accept(*this); appendCode() << "} 1 {\n"; if (_loopExpression) + { + Arithmetic previousArithmetic = m_context.arithmetic(); + if (_isSimpleCounterLoop) + m_context.setArithmetic(Arithmetic::Wrapping); _loopExpression->accept(*this); + m_context.setArithmetic(previousArithmetic); + } appendCode() << "}\n"; appendCode() << "{\n"; diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.h b/libsolidity/codegen/ir/IRGeneratorForStatements.h index 11f8b3c84..e7a478f2d 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.h +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.h @@ -235,7 +235,8 @@ private: Expression const* _conditionExpression, Statement const* _initExpression = nullptr, ExpressionStatement const* _loopExpression = nullptr, - bool _isDoWhile = false + bool _isDoWhile = false, + bool _isSimpleCounterLoop = false ); static Type const& type(Expression const& _expression); From 0acab9d07e6c70a4a3f2362e7f8e0e24a6eb0392 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 13 Jun 2023 13:41:36 +0200 Subject: [PATCH 2/9] fixup! previous reviews fixups --- libsolidity/analysis/PostTypeChecker.cpp | 51 ++++++++++--------- libsolidity/ast/ASTJsonExporter.cpp | 12 ++--- .../codegen/ir/IRGeneratorForStatements.cpp | 2 +- 3 files changed, 33 insertions(+), 32 deletions(-) diff --git a/libsolidity/analysis/PostTypeChecker.cpp b/libsolidity/analysis/PostTypeChecker.cpp index b68167c1d..0634cdc66 100644 --- a/libsolidity/analysis/PostTypeChecker.cpp +++ b/libsolidity/analysis/PostTypeChecker.cpp @@ -435,18 +435,21 @@ struct ReservedErrorSelector: public PostTypeChecker::Checker class LValueChecker: public ASTConstVisitor { public: - LValueChecker(Identifier const& _identifier): m_declaration(_identifier.annotation().referencedDeclaration) {} + LValueChecker(Identifier const& _identifier): + m_declaration(_identifier.annotation().referencedDeclaration) + {} bool willBeWrittenTo() const { return m_willBeWrittenTo; } void endVisit(Identifier const& _identifier) override { + solAssert(_identifier.annotation().referencedDeclaration); if ( - _identifier.annotation().referencedDeclaration == m_declaration && + *_identifier.annotation().referencedDeclaration == *m_declaration && _identifier.annotation().willBeWrittenTo ) m_willBeWrittenTo = true; } private: - Declaration const* m_declaration; + Declaration const* m_declaration{}; bool m_willBeWrittenTo = false; }; @@ -460,29 +463,27 @@ struct SimpleCounterForLoopChecker: public PostTypeChecker::Checker } bool isSimpleCounterLoop(ForStatement const& _forStatement) const { - auto const* cond = dynamic_cast(_forStatement.condition()); - if (!cond || cond->getOperator() != Token::LessThan || cond->userDefinedFunctionType()) + auto const* simpleCondition = dynamic_cast(_forStatement.condition()); + if (!simpleCondition || simpleCondition->getOperator() != Token::LessThan || simpleCondition->userDefinedFunctionType()) return false; if (!_forStatement.loopExpression()) return false; - auto const* post = dynamic_cast(&_forStatement.loopExpression()->expression()); + auto const* simplePostExpression = dynamic_cast(&_forStatement.loopExpression()->expression()); // This matches both operators ++i and i++ - if (!post || post->getOperator() != Token::Inc || post->userDefinedFunctionType()) + if (!simplePostExpression || simplePostExpression->getOperator() != Token::Inc || simplePostExpression->userDefinedFunctionType()) return false; - auto const* lhsIdentifier = dynamic_cast(&cond->leftExpression()); - auto const* lhsType = dynamic_cast(cond->leftExpression().annotation().type); - auto const *commonType = dynamic_cast(cond->annotation().commonType); + auto const* lhsIdentifier = dynamic_cast(&simpleCondition->leftExpression()); + auto const* lhsIntegerType = dynamic_cast(simpleCondition->leftExpression().annotation().type); + auto const* commonIntegerType = dynamic_cast(simpleCondition->annotation().commonType); - if (lhsIdentifier && lhsType && commonType && *lhsType == *commonType) - { - LValueChecker lValueChecker{*lhsIdentifier}; - _forStatement.body().accept(lValueChecker); - if (!lValueChecker.willBeWrittenTo()) - return true; - } - return false; + if (!lhsIdentifier || !lhsIntegerType || !commonIntegerType || *lhsIntegerType != *commonIntegerType) + return false; + + LValueChecker lhsLValueChecker{*lhsIdentifier}; + _forStatement.body().accept(lhsLValueChecker); + return !lhsLValueChecker.willBeWrittenTo(); } }; @@ -491,11 +492,11 @@ struct SimpleCounterForLoopChecker: public PostTypeChecker::Checker PostTypeChecker::PostTypeChecker(langutil::ErrorReporter& _errorReporter): m_errorReporter(_errorReporter) { - m_checkers.push_back(make_shared(_errorReporter)); - m_checkers.push_back(make_shared(_errorReporter)); - m_checkers.push_back(make_shared(_errorReporter)); - m_checkers.push_back(make_shared(_errorReporter)); - m_checkers.push_back(make_shared(_errorReporter)); - m_checkers.push_back(make_shared(_errorReporter)); - m_checkers.push_back(make_shared(_errorReporter)); + m_checkers.push_back(std::make_shared(_errorReporter)); + m_checkers.push_back(std::make_shared(_errorReporter)); + m_checkers.push_back(std::make_shared(_errorReporter)); + m_checkers.push_back(std::make_shared(_errorReporter)); + m_checkers.push_back(std::make_shared(_errorReporter)); + m_checkers.push_back(std::make_shared(_errorReporter)); + m_checkers.push_back(std::make_shared(_errorReporter)); } diff --git a/libsolidity/ast/ASTJsonExporter.cpp b/libsolidity/ast/ASTJsonExporter.cpp index 251622195..cd346ca06 100644 --- a/libsolidity/ast/ASTJsonExporter.cpp +++ b/libsolidity/ast/ASTJsonExporter.cpp @@ -743,15 +743,15 @@ bool ASTJsonExporter::visit(WhileStatement const& _node) bool ASTJsonExporter::visit(ForStatement const& _node) { - std::vector> attributes = { - make_pair("initializationExpression", toJsonOrNull(_node.initializationExpression())), - make_pair("condition", toJsonOrNull(_node.condition())), - make_pair("loopExpression", toJsonOrNull(_node.loopExpression())), - make_pair("body", toJson(_node.body())) + std::vector> attributes = { + std::make_pair("initializationExpression", toJsonOrNull(_node.initializationExpression())), + std::make_pair("condition", toJsonOrNull(_node.condition())), + std::make_pair("loopExpression", toJsonOrNull(_node.loopExpression())), + std::make_pair("body", toJson(_node.body())) }; if (_node.annotation().isSimpleCounterLoop.set()) - attributes.emplace_back(make_pair("isSimpleCounterLoop", *_node.annotation().isSimpleCounterLoop)); + attributes.emplace_back(std::make_pair("isSimpleCounterLoop", *_node.annotation().isSimpleCounterLoop)); setJsonNode(_node, "ForStatement", std::move(attributes)); return false; diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index ffcb1409b..724fe66fd 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -618,7 +618,7 @@ bool IRGeneratorForStatements::visit(ForStatement const& _forStatement) _forStatement.condition(), _forStatement.initializationExpression(), _forStatement.loopExpression(), - false, + false, // _isDoWhile *_forStatement.annotation().isSimpleCounterLoop ); From 2528ff31ee86278d50bc5087d63548a119555fe9 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Tue, 19 Sep 2023 16:53:48 -0300 Subject: [PATCH 3/9] Detect different vars in condition and increment --- libsolidity/analysis/PostTypeChecker.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libsolidity/analysis/PostTypeChecker.cpp b/libsolidity/analysis/PostTypeChecker.cpp index 0634cdc66..676b8e785 100644 --- a/libsolidity/analysis/PostTypeChecker.cpp +++ b/libsolidity/analysis/PostTypeChecker.cpp @@ -481,6 +481,12 @@ struct SimpleCounterForLoopChecker: public PostTypeChecker::Checker if (!lhsIdentifier || !lhsIntegerType || !commonIntegerType || *lhsIntegerType != *commonIntegerType) return false; + if ( + auto const* incExpressionIdentifier = dynamic_cast(&simplePostExpression->subExpression()); + incExpressionIdentifier->annotation().referencedDeclaration != lhsIdentifier->annotation().referencedDeclaration + ) + return false; + LValueChecker lhsLValueChecker{*lhsIdentifier}; _forStatement.body().accept(lhsLValueChecker); return !lhsLValueChecker.willBeWrittenTo(); From 0cb4bd9308843a765bd90b305bce2396f7f5f2a4 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Wed, 20 Sep 2023 16:58:19 -0300 Subject: [PATCH 4/9] Detect var being assigned in inline assembly block --- libsolidity/analysis/PostTypeChecker.cpp | 25 ++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/libsolidity/analysis/PostTypeChecker.cpp b/libsolidity/analysis/PostTypeChecker.cpp index 676b8e785..322473e25 100644 --- a/libsolidity/analysis/PostTypeChecker.cpp +++ b/libsolidity/analysis/PostTypeChecker.cpp @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include @@ -432,6 +434,23 @@ struct ReservedErrorSelector: public PostTypeChecker::Checker } }; +class YulLValueChecker : public solidity::yul::ASTWalker +{ +public: + YulLValueChecker(ASTString const& _identifierName): m_identifierName(_identifierName) {} + bool willBeWrittenTo() { return m_willBeWrittenTo; } + using solidity::yul::ASTWalker::operator(); + void operator()(solidity::yul::Assignment const& _assignment) override + { + for (auto const& yulIdentifier: _assignment.variableNames) + if (yulIdentifier.name.str() == m_identifierName) + m_willBeWrittenTo = true; + } +private: + ASTString const& m_identifierName; + bool m_willBeWrittenTo = false; +}; + class LValueChecker: public ASTConstVisitor { public: @@ -448,6 +467,12 @@ public: ) m_willBeWrittenTo = true; } + void endVisit(InlineAssembly const& _inlineAssembly) override + { + YulLValueChecker yulChecker{m_declaration->name()}; + yulChecker(_inlineAssembly.operations()); + m_willBeWrittenTo = yulChecker.willBeWrittenTo(); + } private: Declaration const* m_declaration{}; bool m_willBeWrittenTo = false; From 52e6090bfbd0700f1d4b7a27076c8c97532385bd Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Thu, 21 Sep 2023 18:12:16 -0300 Subject: [PATCH 5/9] Activate if any optimization is on --- libsolidity/codegen/ContractCompiler.cpp | 2 +- libsolidity/codegen/ir/IRGenerator.cpp | 14 +++++++------- libsolidity/codegen/ir/IRGenerator.h | 8 ++++++-- .../codegen/ir/IRGeneratorForStatements.cpp | 4 ++-- libsolidity/codegen/ir/IRGeneratorForStatements.h | 6 +++++- libsolidity/interface/CompilerStack.cpp | 3 ++- libsolidity/interface/OptimiserSettings.h | 5 +++++ .../externalContracts/deposit_contract.sol | 2 +- 8 files changed, 29 insertions(+), 15 deletions(-) diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 465c284a6..011b5a470 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -1249,7 +1249,7 @@ bool ContractCompiler::visit(ForStatement const& _forStatement) Arithmetic previousArithmetic = m_context.arithmetic(); if ( *_forStatement.annotation().isSimpleCounterLoop && - m_optimiserSettings == OptimiserSettings::standard() + m_optimiserSettings != OptimiserSettings::none() ) m_context.setArithmetic(Arithmetic::Wrapping); _forStatement.loopExpression()->accept(*this); diff --git a/libsolidity/codegen/ir/IRGenerator.cpp b/libsolidity/codegen/ir/IRGenerator.cpp index e3375c692..db4cafca5 100644 --- a/libsolidity/codegen/ir/IRGenerator.cpp +++ b/libsolidity/codegen/ir/IRGenerator.cpp @@ -224,7 +224,7 @@ std::string IRGenerator::generate( std::string IRGenerator::generate(Block const& _block) { - IRGeneratorForStatements generator(m_context, m_utils); + IRGeneratorForStatements generator(m_context, m_utils, m_optimiserSettings); generator.generate(_block); return generator.code(); } @@ -447,7 +447,7 @@ std::string IRGenerator::generateModifier( (!_modifierInvocation.arguments() || _modifierInvocation.arguments()->empty()), "" ); - IRGeneratorForStatements expressionEvaluator(m_context, m_utils); + IRGeneratorForStatements expressionEvaluator(m_context, m_utils, m_optimiserSettings); if (_modifierInvocation.arguments()) for (size_t i = 0; i < _modifierInvocation.arguments()->size(); i++) { @@ -462,7 +462,7 @@ std::string IRGenerator::generateModifier( } t("evalArgs", expressionEvaluator.code()); - IRGeneratorForStatements generator(m_context, m_utils, [&]() { + IRGeneratorForStatements generator(m_context, m_utils, m_optimiserSettings, [&]() { std::string ret = joinHumanReadable(retParams); return (ret.empty() ? "" : ret + " := ") + @@ -572,7 +572,7 @@ std::string IRGenerator::generateGetter(VariableDeclaration const& _varDecl) dispenseLocationComment(m_context.mostDerivedContract()) ) ("functionName", functionName) - ("constantValueFunction", IRGeneratorForStatements(m_context, m_utils).constantValueFunction(_varDecl)) + ("constantValueFunction", IRGeneratorForStatements(m_context, m_utils, m_optimiserSettings).constantValueFunction(_varDecl)) ("ret", suffixedVariableNameList("ret_", 0, _varDecl.type()->sizeOnStack())) .render(); } @@ -747,7 +747,7 @@ std::string IRGenerator::generateExternalFunction(ContractDefinition const& _con std::string IRGenerator::generateInitialAssignment(VariableDeclaration const& _varDecl) { - IRGeneratorForStatements generator(m_context, m_utils); + IRGeneratorForStatements generator(m_context, m_utils, m_optimiserSettings); generator.initializeLocalVar(_varDecl); return generator.code(); } @@ -796,7 +796,7 @@ std::pairarguments() ).second, ""); - IRGeneratorForStatements generator{m_context, m_utils}; + IRGeneratorForStatements generator{m_context, m_utils, m_optimiserSettings}; for (auto&& [baseContract, arguments]: baseConstructorArguments) { solAssert(baseContract && arguments, ""); @@ -817,7 +817,7 @@ std::pairisConstant()) generator.initializeStateVar(*variable); diff --git a/libsolidity/codegen/ir/IRGenerator.h b/libsolidity/codegen/ir/IRGenerator.h index fafe47128..9026954d6 100644 --- a/libsolidity/codegen/ir/IRGenerator.h +++ b/libsolidity/codegen/ir/IRGenerator.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -51,7 +52,8 @@ public: RevertStrings _revertStrings, std::map _sourceIndices, langutil::DebugInfoSelection const& _debugInfoSelection, - langutil::CharStreamProvider const* _soliditySourceProvider + langutil::CharStreamProvider const* _soliditySourceProvider, + OptimiserSettings& _optimiserSettings ): m_evmVersion(_evmVersion), m_eofVersion(_eofVersion), @@ -63,7 +65,8 @@ public: _debugInfoSelection, _soliditySourceProvider ), - m_utils(_evmVersion, m_context.revertStrings(), m_context.functionCollector()) + m_utils(_evmVersion, m_context.revertStrings(), m_context.functionCollector()), + m_optimiserSettings(_optimiserSettings) {} /// Generates and returns (unoptimized) IR code. @@ -141,6 +144,7 @@ private: IRGenerationContext m_context; YulUtilFunctions m_utils; + OptimiserSettings m_optimiserSettings; }; } diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 724fe66fd..9033f739e 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -352,7 +352,7 @@ std::string IRGeneratorForStatements::constantValueFunction(VariableDeclaration )"); templ("sourceLocationComment", dispenseLocationComment(_constant, m_context)); templ("functionName", functionName); - IRGeneratorForStatements generator(m_context, m_utils); + IRGeneratorForStatements generator(m_context, m_utils, m_optimiserSettings); solAssert(_constant.value()); Type const& constantType = *_constant.type(); templ("value", generator.evaluateExpression(*_constant.value(), constantType).commaSeparatedList()); @@ -3214,7 +3214,7 @@ void IRGeneratorForStatements::generateLoop( if (_loopExpression) { Arithmetic previousArithmetic = m_context.arithmetic(); - if (_isSimpleCounterLoop) + if (m_optimiserSettings != OptimiserSettings::none() && _isSimpleCounterLoop) m_context.setArithmetic(Arithmetic::Wrapping); _loopExpression->accept(*this); m_context.setArithmetic(previousArithmetic); diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.h b/libsolidity/codegen/ir/IRGeneratorForStatements.h index e7a478f2d..f4ce2a7d0 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.h +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.h @@ -24,6 +24,7 @@ #include #include #include +#include #include @@ -65,11 +66,13 @@ public: IRGeneratorForStatements( IRGenerationContext& _context, YulUtilFunctions& _utils, + OptimiserSettings& _optimiserSettings, std::function _placeholderCallback = {} ): IRGeneratorForStatementsBase(_context), m_placeholderCallback(std::move(_placeholderCallback)), - m_utils(_utils) + m_utils(_utils), + m_optimiserSettings(_optimiserSettings) {} std::string code() const override; @@ -246,6 +249,7 @@ private: std::function m_placeholderCallback; YulUtilFunctions& m_utils; std::optional m_currentLValue; + OptimiserSettings m_optimiserSettings; }; } diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 44413afdf..b24f45989 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -1498,7 +1498,8 @@ void CompilerStack::generateIR(ContractDefinition const& _contract) m_revertStrings, sourceIndices(), m_debugInfoSelection, - this + this, + m_optimiserSettings ); compiledContract.yulIR = generator.run( _contract, diff --git a/libsolidity/interface/OptimiserSettings.h b/libsolidity/interface/OptimiserSettings.h index 9f2197d42..e2c8e26ff 100644 --- a/libsolidity/interface/OptimiserSettings.h +++ b/libsolidity/interface/OptimiserSettings.h @@ -123,6 +123,11 @@ struct OptimiserSettings expectedExecutionsPerDeployment == _other.expectedExecutionsPerDeployment; } + bool operator!=(OptimiserSettings const& _other) const + { + return !(*this == _other); + } + /// Move literals to the right of commutative binary operators during code generation. /// This helps exploiting associativity. bool runOrderLiterals = false; diff --git a/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol b/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol index e51eb414a..8108e64f4 100644 --- a/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol +++ b/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol @@ -178,7 +178,7 @@ contract DepositContract is IDepositContract, ERC165 { // constructor() // gas irOptimized: 1397699 // gas legacy: 2391952 -// gas legacyOptimized: 1752320 +// gas legacyOptimized: 1740144 // supportsInterface(bytes4): 0x0 -> 0 // supportsInterface(bytes4): 0xffffffff00000000000000000000000000000000000000000000000000000000 -> false # defined to be false by ERC-165 # // supportsInterface(bytes4): 0x01ffc9a700000000000000000000000000000000000000000000000000000000 -> true # ERC-165 id # From a9dbd7a930a540784d894ca654d59b16ae46f523 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Thu, 21 Sep 2023 19:01:02 -0300 Subject: [PATCH 6/9] fix Changelog --- Changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index aa80aaede..13ef1b5ab 100644 --- a/Changelog.md +++ b/Changelog.md @@ -6,6 +6,7 @@ Language Features: Compiler Features: * Parser: Remove the experimental error recovery mode (``--error-recovery`` / ``settings.parserErrorRecovery``). + * Code Generator: Remove redundant overflow checks in specific for loops. * Yul Optimizer: If ``PUSH0`` is supported, favor zero literals over storing zero values in variables. * Yul Optimizer: Run the ``Rematerializer`` and ``UnusedPruner`` steps at the end of the default clean-up sequence. @@ -30,7 +31,6 @@ Language Features: Compiler Features: - * Code Generator: Remove redundant overflow checks in specific for loops. * Commandline Interface: Add ``--ast-compact-json`` output in assembler mode. * Commandline Interface: Add ``--ir-ast-json`` and ``--ir-optimized-ast-json`` outputs for Solidity input, providing AST in compact JSON format for IR and optimized IR. * Commandline Interface: Respect ``--optimize-yul`` and ``--no-optimize-yul`` in compiler mode and accept them in assembler mode as well. ``--optimize --no-optimize-yul`` combination now allows enabling EVM assembly optimizer without enabling Yul optimizer. From fb24ddf2335af4d8ca0bcea79c4bb5e32f2f3a60 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Fri, 22 Sep 2023 16:18:14 -0300 Subject: [PATCH 7/9] Added tests --- .../forLoop/isSimpleCounterLoop.sol | 187 ++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 test/libsolidity/astPropertyTests/forLoop/isSimpleCounterLoop.sol diff --git a/test/libsolidity/astPropertyTests/forLoop/isSimpleCounterLoop.sol b/test/libsolidity/astPropertyTests/forLoop/isSimpleCounterLoop.sol new file mode 100644 index 000000000..624a79312 --- /dev/null +++ b/test/libsolidity/astPropertyTests/forLoop/isSimpleCounterLoop.sol @@ -0,0 +1,187 @@ +type UINT is uint; + +function add(UINT x, UINT y) pure returns (UINT) { + return UINT.wrap(UINT.unwrap(x) + UINT.unwrap(y)); +} + +function lt(UINT x, UINT y) pure returns (bool) { + return UINT.unwrap(x) < UINT.unwrap(y); +} + +using {lt as <, add as +} for UINT global; + +function g() pure returns (bool) { + return false; +} + +function h() pure returns (uint) { + return 13; +} + +contract C { + uint[] dynArray; + uint z = 0; + + function modifyStateVarZ() public returns (uint) { + z = type(uint).max; + return z; + } + + function f() public { + /// PositiveCase1: isSimpleCounterLoop + for(uint i = 0; i < 42; ++i) { + } + /// PositiveCase2: isSimpleCounterLoop + for(int i = 0; i < 42; i++) { + } + uint x; + /// PositiveCase3: isSimpleCounterLoop + for(uint i = 0; i < 42; i++) { + x = i; + } + /// PositiveCase4: isSimpleCounterLoop + for(uint i = 0; i < x; i++) { + } + uint[8] memory array; + /// PositiveCase5: isSimpleCounterLoop + for(uint i = 0; i < array.length; i++) { + } + dynArray.push(); + /// PositiveCase6: isSimpleCounterLoop + for(uint i = 0; i < dynArray.length; i++) { + dynArray.push(i); + } + /// PositiveCase7: isSimpleCounterLoop + for(uint i = 0; i < 42; ++i) { + assembly { + x := i + } + } + /// PositiveCase8: isSimpleCounterLoop + for(uint i = 0; i < i + 1; i++) { + } + /// PositiveCase9: isSimpleCounterLoop + for(uint i = 0; i < h(); ++i) { + } + /// NegativeCase1: isSimpleCounterLoop + for(uint i = 0; i < 42; i = i + 1) { + } + /// NegativeCase2: isSimpleCounterLoop + for(uint i = 42; i > 0; --i) { + } + /// NegativeCase3: isSimpleCounterLoop + for(uint i = 42; i > 0; i--) { + } + /// NegativeCase4: isSimpleCounterLoop + for(uint i = 1; i < 42; i = i * 2) { + } + /// NegativeCase5: isSimpleCounterLoop + for(uint i = 0; i < 42; ++i) { + i++; + } + /// NegativeCase6: isSimpleCounterLoop + for(uint i = 0; i < 42; ++i) { + i = 43; + } + /// NegativeCase7: isSimpleCounterLoop + for(uint i = 0; i < 42; ++i) { + assembly { + i := add(i, 1) + } + } + uint j = type(uint).max; + /// NegativeCase8: isSimpleCounterLoop + for (uint i = 0; i < 10; ++j) { + } + /// NegativeCase9: isSimpleCounterLoop + for(uint i = 0; i < 10; ++i) { + x = i++; + } + /// NegativeCase10: isSimpleCounterLoop + for(uint i = 0; i < 42; i) { + } + uint y = type(uint8).max + 1; + /// NegativeCase11: isSimpleCounterLoop + for(uint8 i = 0; i < y; ++i) { + } + /// NegativeCase12: isSimpleCounterLoop + for(uint i = 0; i < 10; ) { + } + /// NegativeCase13: isSimpleCounterLoop + for(uint i = 0; i <= 10; ++i) { + } + /// NegativeCase14: isSimpleCounterLoop + for(uint i = 0; (i < 10 || g()); ++i) { + } + /// NegativeCase15: isSimpleCounterLoop + for(uint i = 0; h() < 100; ++i) { + } + /// NegativeCase16: isSimpleCounterLoop + for(uint i = 0; address(this) < msg.sender; ++i) { + } + /// NegativeCase17: isSimpleCounterLoop + for(UINT i = UINT.wrap(0); i < UINT.wrap(10); i = i + UINT.wrap(1)) { + } + /// NegativeCase18: isSimpleCounterLoop + for(uint i = 0; i < 42; ++i) { + i = 43; + } + /// NegativeCase19: isSimpleCounterLoop + for(uint i = 0; i < (i = i + 1); ++i) { + } + /// NegativeCase20: isSimpleCounterLoop + for(uint8 i = 0; i < 257 ; ++i) { + } + /// NegativeCase21: isSimpleCounterLoop + for(uint8 i = 0; i < h(); ++i) { + } + /// NegativeCase22: isSimpleCounterLoop + for (z = 1; z < modifyStateVarZ(); ++z) { + } + /// NegativeCase23: isSimpleCounterLoop + for (address i = address(0x123); i < address(this); i = address(0x123 + 1)) { + } + uint16 w = 512; + /// NegativeCase24: isSimpleCounterLoop + for(uint8 i = 0; i < w; ++i) { + } + /// NegativeCase25: isSimpleCounterLoop + for(uint8 i = 0; i < h(); ++i) { + } + } +} +// ---- +// PositiveCase1: true +// PositiveCase2: true +// PositiveCase3: true +// PositiveCase4: true +// PositiveCase5: true +// PositiveCase6: true +// PositiveCase7: true +// PositiveCase8: true +// PositiveCase9: true +// NegativeCase1: false +// NegativeCase2: false +// NegativeCase3: false +// NegativeCase4: false +// NegativeCase5: false +// NegativeCase6: false +// NegativeCase7: false +// NegativeCase8: false +// NegativeCase9: false +// NegativeCase10: false +// NegativeCase11: false +// NegativeCase12: false +// NegativeCase13: false +// NegativeCase14: false +// NegativeCase15: false +// NegativeCase16: false +// NegativeCase17: false +// NegativeCase18: false +// NegativeCase19: true +// NegativeCase20: false +// NegativeCase21: false +// NegativeCase22: true +// NegativeCase23: false +// NegativeCase24: false +// NegativeCase25: false From 91f93de2ad242a3a543a7c186f9b7afbae1f969b Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Fri, 22 Sep 2023 17:09:44 -0300 Subject: [PATCH 8/9] Rename test cases --- .../forLoop/isSimpleCounterLoop.sol | 155 +++++++++--------- 1 file changed, 74 insertions(+), 81 deletions(-) diff --git a/test/libsolidity/astPropertyTests/forLoop/isSimpleCounterLoop.sol b/test/libsolidity/astPropertyTests/forLoop/isSimpleCounterLoop.sol index 624a79312..61c2b8ffc 100644 --- a/test/libsolidity/astPropertyTests/forLoop/isSimpleCounterLoop.sol +++ b/test/libsolidity/astPropertyTests/forLoop/isSimpleCounterLoop.sol @@ -28,160 +28,153 @@ contract C { } function f() public { - /// PositiveCase1: isSimpleCounterLoop + // Positive Cases + /// SimplePreIncrement: isSimpleCounterLoop for(uint i = 0; i < 42; ++i) { } - /// PositiveCase2: isSimpleCounterLoop + /// SimplePosIncrement: isSimpleCounterLoop for(int i = 0; i < 42; i++) { } uint x; - /// PositiveCase3: isSimpleCounterLoop + /// CounterReadLoopBody: isSimpleCounterLoop for(uint i = 0; i < 42; i++) { x = i; } - /// PositiveCase4: isSimpleCounterLoop + /// LocalVarConditionRHS: isSimpleCounterLoop for(uint i = 0; i < x; i++) { } uint[8] memory array; - /// PositiveCase5: isSimpleCounterLoop + /// StaticArrayLengthConditionRHS: isSimpleCounterLoop for(uint i = 0; i < array.length; i++) { } dynArray.push(); - /// PositiveCase6: isSimpleCounterLoop + /// DynamicArrayLengthConditionRHS: isSimpleCounterLoop for(uint i = 0; i < dynArray.length; i++) { dynArray.push(i); } - /// PositiveCase7: isSimpleCounterLoop + /// CounterReadInlineAssembly: isSimpleCounterLoop for(uint i = 0; i < 42; ++i) { assembly { x := i } } - /// PositiveCase8: isSimpleCounterLoop + /// BinaryOperationConditionRHS: isSimpleCounterLoop for(uint i = 0; i < i + 1; i++) { } - /// PositiveCase9: isSimpleCounterLoop + /// FreeFunctionConditionRHS: isSimpleCounterLoop for(uint i = 0; i < h(); ++i) { } - /// NegativeCase1: isSimpleCounterLoop + // Negative Cases + /// AdditionLoopExpression: isSimpleCounterLoop for(uint i = 0; i < 42; i = i + 1) { } - /// NegativeCase2: isSimpleCounterLoop + /// SimplePreDecrement: isSimpleCounterLoop for(uint i = 42; i > 0; --i) { } - /// NegativeCase3: isSimpleCounterLoop + /// SimplePosDecrement: isSimpleCounterLoop for(uint i = 42; i > 0; i--) { } - /// NegativeCase4: isSimpleCounterLoop + /// MultiplicationLoopExpression: isSimpleCounterLoop for(uint i = 1; i < 42; i = i * 2) { } - /// NegativeCase5: isSimpleCounterLoop + /// CounterIncrementLoopBody: isSimpleCounterLoop for(uint i = 0; i < 42; ++i) { i++; } - /// NegativeCase6: isSimpleCounterLoop + /// CounterAssignmentLoopBody: isSimpleCounterLoop for(uint i = 0; i < 42; ++i) { i = 43; } - /// NegativeCase7: isSimpleCounterLoop + /// CounterAssignmentInlineAssemblyLoopBody: isSimpleCounterLoop for(uint i = 0; i < 42; ++i) { assembly { i := add(i, 1) } } uint j = type(uint).max; - /// NegativeCase8: isSimpleCounterLoop + /// ExternalCounterLoopExpression: isSimpleCounterLoop for (uint i = 0; i < 10; ++j) { } - /// NegativeCase9: isSimpleCounterLoop + /// CounterIncrementRHSAssignment: isSimpleCounterLoop for(uint i = 0; i < 10; ++i) { x = i++; } - /// NegativeCase10: isSimpleCounterLoop + /// NoEffectLoopExpression: isSimpleCounterLoop for(uint i = 0; i < 42; i) { } - uint y = type(uint8).max + 1; - /// NegativeCase11: isSimpleCounterLoop - for(uint8 i = 0; i < y; ++i) { - } - /// NegativeCase12: isSimpleCounterLoop + /// EmptyLoopExpression: isSimpleCounterLoop for(uint i = 0; i < 10; ) { } - /// NegativeCase13: isSimpleCounterLoop + uint y = type(uint8).max + 1; + /// DifferentCommonTypeCondition: isSimpleCounterLoop + for(uint8 i = 0; i < y; ++i) { + } + /// LessThanOrEqualCondition: isSimpleCounterLoop for(uint i = 0; i <= 10; ++i) { } - /// NegativeCase14: isSimpleCounterLoop + /// ComplexExpressionCondition: isSimpleCounterLoop for(uint i = 0; (i < 10 || g()); ++i) { } - /// NegativeCase15: isSimpleCounterLoop + /// FreeFunctionConditionLHS: isSimpleCounterLoop for(uint i = 0; h() < 100; ++i) { } - /// NegativeCase16: isSimpleCounterLoop + /// FreeFunctionConditionDifferentCommonTypeLHS: isSimpleCounterLoop + for(uint8 i = 0; i < h(); ++i) { + } + /// NonIntegerTypeCondition: isSimpleCounterLoop for(uint i = 0; address(this) < msg.sender; ++i) { } - /// NegativeCase17: isSimpleCounterLoop + /// UDVTOperators: isSimpleCounterLoop for(UINT i = UINT.wrap(0); i < UINT.wrap(10); i = i + UINT.wrap(1)) { } - /// NegativeCase18: isSimpleCounterLoop - for(uint i = 0; i < 42; ++i) { - i = 43; - } - /// NegativeCase19: isSimpleCounterLoop + /// CounterAssignmentConditionRHS: isSimpleCounterLoop for(uint i = 0; i < (i = i + 1); ++i) { } - /// NegativeCase20: isSimpleCounterLoop + /// LiteralDifferentCommonTypeConditionRHS: isSimpleCounterLoop for(uint8 i = 0; i < 257 ; ++i) { } - /// NegativeCase21: isSimpleCounterLoop - for(uint8 i = 0; i < h(); ++i) { - } - /// NegativeCase22: isSimpleCounterLoop + /// StateVarCounterModifiedFunctionConditionRHS: isSimpleCounterLoop for (z = 1; z < modifyStateVarZ(); ++z) { } - /// NegativeCase23: isSimpleCounterLoop + /// StateVarCounterModifiedFunctionLoopBody: isSimpleCounterLoop + for (z = 1; z < 2048; ++z) { + modifyStateVarZ(); + } + /// NonIntegerCounter: isSimpleCounterLoop for (address i = address(0x123); i < address(this); i = address(0x123 + 1)) { } - uint16 w = 512; - /// NegativeCase24: isSimpleCounterLoop - for(uint8 i = 0; i < w; ++i) { - } - /// NegativeCase25: isSimpleCounterLoop - for(uint8 i = 0; i < h(); ++i) { - } } } // ---- -// PositiveCase1: true -// PositiveCase2: true -// PositiveCase3: true -// PositiveCase4: true -// PositiveCase5: true -// PositiveCase6: true -// PositiveCase7: true -// PositiveCase8: true -// PositiveCase9: true -// NegativeCase1: false -// NegativeCase2: false -// NegativeCase3: false -// NegativeCase4: false -// NegativeCase5: false -// NegativeCase6: false -// NegativeCase7: false -// NegativeCase8: false -// NegativeCase9: false -// NegativeCase10: false -// NegativeCase11: false -// NegativeCase12: false -// NegativeCase13: false -// NegativeCase14: false -// NegativeCase15: false -// NegativeCase16: false -// NegativeCase17: false -// NegativeCase18: false -// NegativeCase19: true -// NegativeCase20: false -// NegativeCase21: false -// NegativeCase22: true -// NegativeCase23: false -// NegativeCase24: false -// NegativeCase25: false +// SimplePreIncrement: true +// SimplePosIncrement: true +// CounterReadLoopBody: true +// LocalVarConditionRHS: true +// StaticArrayLengthConditionRHS: true +// DynamicArrayLengthConditionRHS: true +// CounterReadInlineAssembly: true +// BinaryOperationConditionRHS: true +// FreeFunctionConditionRHS: true +// AdditionLoopExpression: false +// SimplePreDecrement: false +// SimplePosDecrement: false +// MultiplicationLoopExpression: false +// CounterIncrementLoopBody: false +// CounterAssignmentLoopBody: false +// CounterAssignmentInlineAssemblyLoopBody: false +// ExternalCounterLoopExpression: false +// CounterIncrementRHSAssignment: false +// NoEffectLoopExpression: false +// DifferentCommonTypeCondition: false +// EmptyLoopExpression: false +// LessThanOrEqualCondition: false +// ComplexExpressionCondition: false +// FreeFunctionConditionLHS: false +// FreeFunctionConditionDifferentCommonTypeLHS: false +// NonIntegerTypeCondition: false +// UDVTOperators: false +// CounterAssignmentConditionRHS: true +// LiteralDifferentCommonTypeConditionRHS: false +// StateVarCounterModifiedFunctionConditionRHS: true +// StateVarCounterModifiedFunctionLoopBody: true +// NonIntegerCounter: false From af116a9500e97a153e0d4547a3f06afb708b24a0 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Fri, 22 Sep 2023 16:17:57 -0300 Subject: [PATCH 9/9] Update tests --- .../cmdlineTests/optimizer_array_sload/output | 9 +--- .../ASTJSON/documentation_local_variable.json | 1 + .../ASTJSON/documentation_local_variable.sol | 1 + .../ASTJSON/documentation_on_statements.json | 1 + .../ASTJSON/documentation_on_statements.sol | 1 + .../ASTJSON/documentation_triple.json | 1 + .../ASTJSON/documentation_triple.sol | 1 + .../abi_encode_calldata_slice.sol | 12 ++--- .../abi_encode_calldata_slice.sol | 12 ++--- .../abiEncoderV2/calldata_array.sol | 4 +- .../array/array_memory_index_access.sol | 6 +-- .../array/array_storage_index_access.sol | 54 +++++++++---------- .../array/array_storage_index_zeroed_test.sol | 24 ++++----- .../array/array_storage_push_empty.sol | 12 ++--- .../array/byte_array_storage_layout.sol | 4 +- .../array/byte_array_transitional_2.sol | 6 +-- .../copying/array_copy_different_packing.sol | 6 +-- .../copying/array_copy_including_array.sol | 12 ++--- .../copying/array_copy_target_leftover.sol | 6 +-- .../copying/array_copy_target_simple.sol | 6 +-- .../copying/array_copy_target_simple_2.sol | 6 +-- ..._containing_arrays_calldata_to_storage.sol | 2 +- .../copying/bytes_storage_to_storage.sol | 30 +++++------ .../memory_dyn_2d_bytes_to_storage.sol | 6 +-- .../array/copying/storage_memory_nested.sol | 6 +-- .../storage_memory_nested_from_pointer.sol | 6 +-- .../copying/storage_memory_packed_dyn.sol | 6 +-- .../array/delete/bytes_delete_element.sol | 6 +-- .../array/dynamic_array_cleanup.sol | 6 +-- .../array/fixed_array_cleanup.sol | 6 +-- .../array/function_array_cross_calls.sol | 6 +-- .../array/pop/byte_array_pop_masking_long.sol | 6 +-- .../array/push/byte_array_push_transition.sol | 6 +-- .../array/push/push_no_args_bytes.sol | 6 +-- .../events/event_indexed_string.sol | 6 +-- .../externalContracts/base64.sol | 18 +++---- .../externalContracts/deposit_contract.sol | 28 +++++----- .../externalContracts/prbmath_signed.sol | 6 +-- .../externalContracts/prbmath_unsigned.sol | 6 +-- .../externalContracts/ramanujan_pi.sol | 8 +-- .../semanticTests/externalContracts/snark.sol | 12 ++--- .../externalContracts/strings.sol | 12 ++--- .../libraries/internal_types_in_library.sol | 6 +-- .../userDefinedValueType/calldata.sol | 12 ++--- 44 files changed, 198 insertions(+), 199 deletions(-) diff --git a/test/cmdlineTests/optimizer_array_sload/output b/test/cmdlineTests/optimizer_array_sload/output index 2698a60cf..b32d421d0 100644 --- a/test/cmdlineTests/optimizer_array_sload/output +++ b/test/cmdlineTests/optimizer_array_sload/output @@ -34,15 +34,8 @@ object "Arraysum_34" { /** @src 0:380:397 "i < values.length" */ lt(var_i, _2) /// @src 0:368:378 "uint i = 0" { - /// @src 0:80:429 "contract Arraysum {..." - if eq(var_i, not(0)) - { - mstore(0, shl(224, 0x4e487b71)) - mstore(_1, 0x11) - revert(0, 0x24) - } /// @src 0:399:402 "i++" - var_i := /** @src 0:80:429 "contract Arraysum {..." */ add(var_i, 1) + var_i := /** @src 0:80:429 "contract Arraysum {..." */ add(/** @src 0:399:402 "i++" */ var_i, /** @src 0:80:429 "contract Arraysum {..." */ 1) } /// @src 0:399:402 "i++" { diff --git a/test/libsolidity/ASTJSON/documentation_local_variable.json b/test/libsolidity/ASTJSON/documentation_local_variable.json index edaa89c18..62d76e782 100644 --- a/test/libsolidity/ASTJSON/documentation_local_variable.json +++ b/test/libsolidity/ASTJSON/documentation_local_variable.json @@ -283,6 +283,7 @@ "nodeType": "VariableDeclarationStatement", "src": "212:10:1" }, + "isSimpleCounterLoop": true, "loopExpression": { "expression": diff --git a/test/libsolidity/ASTJSON/documentation_local_variable.sol b/test/libsolidity/ASTJSON/documentation_local_variable.sol index a593e0194..b21602d92 100644 --- a/test/libsolidity/ASTJSON/documentation_local_variable.sol +++ b/test/libsolidity/ASTJSON/documentation_local_variable.sol @@ -21,4 +21,5 @@ contract C { uint param3 ) public {} } + // ---- diff --git a/test/libsolidity/ASTJSON/documentation_on_statements.json b/test/libsolidity/ASTJSON/documentation_on_statements.json index f7b424ea6..cc4a1ef3c 100644 --- a/test/libsolidity/ASTJSON/documentation_on_statements.json +++ b/test/libsolidity/ASTJSON/documentation_on_statements.json @@ -244,6 +244,7 @@ "nodeType": "VariableDeclarationStatement", "src": "131:10:1" }, + "isSimpleCounterLoop": true, "loopExpression": { "expression": diff --git a/test/libsolidity/ASTJSON/documentation_on_statements.sol b/test/libsolidity/ASTJSON/documentation_on_statements.sol index 9506bb05c..235fa3d20 100644 --- a/test/libsolidity/ASTJSON/documentation_on_statements.sol +++ b/test/libsolidity/ASTJSON/documentation_on_statements.sol @@ -12,4 +12,5 @@ contract C { return x; } } + // ---- diff --git a/test/libsolidity/ASTJSON/documentation_triple.json b/test/libsolidity/ASTJSON/documentation_triple.json index bd6f483b5..cd44bd4eb 100644 --- a/test/libsolidity/ASTJSON/documentation_triple.json +++ b/test/libsolidity/ASTJSON/documentation_triple.json @@ -253,6 +253,7 @@ "nodeType": "VariableDeclarationStatement", "src": "117:10:1" }, + "isSimpleCounterLoop": true, "loopExpression": { "expression": diff --git a/test/libsolidity/ASTJSON/documentation_triple.sol b/test/libsolidity/ASTJSON/documentation_triple.sol index 5b14e58f6..578933d9c 100644 --- a/test/libsolidity/ASTJSON/documentation_triple.sol +++ b/test/libsolidity/ASTJSON/documentation_triple.sol @@ -12,4 +12,5 @@ contract C { return x; } } + // ---- diff --git a/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol b/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol index 53bc3faba..491a64c28 100644 --- a/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol +++ b/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol @@ -59,10 +59,10 @@ contract C { // EVMVersion: >homestead // ---- // test_bytes() -> -// gas irOptimized: 360863 -// gas legacy: 411269 -// gas legacyOptimized: 317754 +// gas irOptimized: 321332 +// gas legacy: 319111 +// gas legacyOptimized: 269317 // test_uint256() -> -// gas irOptimized: 509677 -// gas legacy: 577469 -// gas legacyOptimized: 441003 +// gas irOptimized: 447844 +// gas legacy: 433627 +// gas legacyOptimized: 365410 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol index 975e9f477..7d5d25a44 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol @@ -60,10 +60,10 @@ contract C { // EVMVersion: >homestead // ---- // test_bytes() -> -// gas irOptimized: 360863 -// gas legacy: 411269 -// gas legacyOptimized: 317754 +// gas irOptimized: 321332 +// gas legacy: 319111 +// gas legacyOptimized: 269317 // test_uint256() -> -// gas irOptimized: 509677 -// gas legacy: 577469 -// gas legacyOptimized: 441003 +// gas irOptimized: 447844 +// gas legacy: 433627 +// gas legacyOptimized: 365410 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol b/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol index 12920a70a..22aad6749 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol @@ -20,6 +20,6 @@ contract C { // f(uint256[][1]): 32, 32, 0 -> true // f(uint256[][1]): 32, 32, 1, 42 -> true // f(uint256[][1]): 32, 32, 8, 421, 422, 423, 424, 425, 426, 427, 428 -> true -// gas irOptimized: 126851 -// gas legacy: 139800 +// gas irOptimized: 120043 +// gas legacy: 101568 // gas legacyOptimized: 119092 diff --git a/test/libsolidity/semanticTests/array/array_memory_index_access.sol b/test/libsolidity/semanticTests/array/array_memory_index_access.sol index e8b6cd48f..d313e7acb 100644 --- a/test/libsolidity/semanticTests/array/array_memory_index_access.sol +++ b/test/libsolidity/semanticTests/array/array_memory_index_access.sol @@ -26,9 +26,9 @@ contract C { // index(uint256): 10 -> true // index(uint256): 20 -> true // index(uint256): 0xFF -> true -// gas irOptimized: 135066 -// gas legacy: 241703 -// gas legacyOptimized: 151613 +// gas irOptimized: 108291 +// gas legacy: 181523 +// gas legacyOptimized: 117443 // accessIndex(uint256,int256): 10, 1 -> 2 // accessIndex(uint256,int256): 10, 0 -> 1 // accessIndex(uint256,int256): 10, 11 -> FAILURE, hex"4e487b71", 0x32 diff --git a/test/libsolidity/semanticTests/array/array_storage_index_access.sol b/test/libsolidity/semanticTests/array/array_storage_index_access.sol index 1ea50824f..2589e4709 100644 --- a/test/libsolidity/semanticTests/array/array_storage_index_access.sol +++ b/test/libsolidity/semanticTests/array/array_storage_index_access.sol @@ -16,38 +16,38 @@ contract C { // ---- // test_indices(uint256): 1 -> // test_indices(uint256): 129 -> -// gas irOptimized: 3016570 -// gas legacy: 3069098 -// gas legacyOptimized: 3013250 +// gas irOptimized: 3003025 +// gas legacy: 3038654 +// gas legacyOptimized: 2995964 // test_indices(uint256): 5 -> -// gas irOptimized: 576716 -// gas legacy: 574754 -// gas legacyOptimized: 572383 +// gas irOptimized: 576296 +// gas legacy: 573810 +// gas legacyOptimized: 571847 // test_indices(uint256): 10 -> -// gas irOptimized: 158059 -// gas legacy: 162468 -// gas legacyOptimized: 158336 +// gas irOptimized: 157009 +// gas legacy: 160108 +// gas legacyOptimized: 156996 // test_indices(uint256): 15 -> -// gas irOptimized: 172984 -// gas legacy: 179513 -// gas legacyOptimized: 173606 +// gas irOptimized: 171409 +// gas legacy: 175973 +// gas legacyOptimized: 171596 // test_indices(uint256): 0xFF -> -// gas irOptimized: 5672104 -// gas legacy: 5775928 -// gas legacyOptimized: 5666726 +// gas irOptimized: 5645329 +// gas legacy: 5715748 +// gas legacyOptimized: 5632556 // test_indices(uint256): 1000 -> -// gas irOptimized: 18173701 -// gas legacy: 18583810 -// gas legacyOptimized: 18171248 +// gas irOptimized: 18068701 +// gas legacy: 18347810 +// gas legacyOptimized: 18037248 // test_indices(uint256): 129 -> -// gas irOptimized: 4147676 -// gas legacy: 4164468 -// gas legacyOptimized: 4122100 +// gas irOptimized: 4136840 +// gas legacy: 4140113 +// gas legacyOptimized: 4108272 // test_indices(uint256): 128 -> -// gas irOptimized: 409209 -// gas legacy: 463706 -// gas legacyOptimized: 418061 +// gas irOptimized: 395769 +// gas legacy: 433498 +// gas legacyOptimized: 400909 // test_indices(uint256): 1 -> -// gas irOptimized: 580316 -// gas legacy: 576904 -// gas legacyOptimized: 575649 +// gas irOptimized: 580232 +// gas legacy: 576715 +// gas legacyOptimized: 575542 diff --git a/test/libsolidity/semanticTests/array/array_storage_index_zeroed_test.sol b/test/libsolidity/semanticTests/array/array_storage_index_zeroed_test.sol index 8a8c9a7c2..593358659 100644 --- a/test/libsolidity/semanticTests/array/array_storage_index_zeroed_test.sol +++ b/test/libsolidity/semanticTests/array/array_storage_index_zeroed_test.sol @@ -52,18 +52,18 @@ contract C { // ---- // test_zeroed_indicies(uint256): 1 -> // test_zeroed_indicies(uint256): 5 -> -// gas irOptimized: 131809 -// gas legacy: 132804 -// gas legacyOptimized: 130649 +// gas irOptimized: 131315 +// gas legacy: 131671 +// gas legacyOptimized: 129994 // test_zeroed_indicies(uint256): 10 -> -// gas irOptimized: 225696 -// gas legacy: 227786 -// gas legacyOptimized: 223830 +// gas irOptimized: 224578 +// gas legacy: 225237 +// gas legacyOptimized: 222359 // test_zeroed_indicies(uint256): 15 -> -// gas irOptimized: 323704 -// gas legacy: 326902 -// gas legacyOptimized: 321206 +// gas irOptimized: 321962 +// gas legacy: 322937 +// gas legacyOptimized: 318919 // test_zeroed_indicies(uint256): 0xFF -> -// gas irOptimized: 5112500 -// gas legacy: 5165874 -// gas legacyOptimized: 5062182 +// gas irOptimized: 5080806 +// gas legacy: 5093941 +// gas legacyOptimized: 5020727 diff --git a/test/libsolidity/semanticTests/array/array_storage_push_empty.sol b/test/libsolidity/semanticTests/array/array_storage_push_empty.sol index 9949b59ea..80376b423 100644 --- a/test/libsolidity/semanticTests/array/array_storage_push_empty.sol +++ b/test/libsolidity/semanticTests/array/array_storage_push_empty.sol @@ -12,13 +12,13 @@ contract C { // EVMVersion: >=petersburg // ---- // pushEmpty(uint256): 128 -// gas irOptimized: 404095 -// gas legacy: 415744 -// gas legacyOptimized: 397380 +// gas irOptimized: 401024 +// gas legacy: 400640 +// gas legacyOptimized: 388804 // pushEmpty(uint256): 256 -// gas irOptimized: 689843 -// gas legacy: 715316 -// gas legacyOptimized: 688632 +// gas irOptimized: 683700 +// gas legacy: 685108 +// gas legacyOptimized: 671480 // pushEmpty(uint256): 38869 -> FAILURE # out-of-gas # // gas irOptimized: 100000000 // gas legacy: 100000000 diff --git a/test/libsolidity/semanticTests/array/byte_array_storage_layout.sol b/test/libsolidity/semanticTests/array/byte_array_storage_layout.sol index e5fd0a2d7..942c7337a 100644 --- a/test/libsolidity/semanticTests/array/byte_array_storage_layout.sol +++ b/test/libsolidity/semanticTests/array/byte_array_storage_layout.sol @@ -46,8 +46,8 @@ contract c { // storageEmpty -> 0 // test_long() -> 67 // gas irOptimized: 89148 -// gas legacy: 105693 -// gas legacyOptimized: 103216 +// gas legacy: 101601 +// gas legacyOptimized: 100477 // storageEmpty -> 0 // test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020 // gas legacy: 61930 diff --git a/test/libsolidity/semanticTests/array/byte_array_transitional_2.sol b/test/libsolidity/semanticTests/array/byte_array_transitional_2.sol index ae3d23a63..3e0f02225 100644 --- a/test/libsolidity/semanticTests/array/byte_array_transitional_2.sol +++ b/test/libsolidity/semanticTests/array/byte_array_transitional_2.sol @@ -17,6 +17,6 @@ contract c { } // ---- // test() -> 0 -// gas irOptimized: 125058 -// gas legacy: 150372 -// gas legacyOptimized: 146391 +// gas irOptimized: 123560 +// gas legacy: 147098 +// gas legacyOptimized: 144200 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_different_packing.sol b/test/libsolidity/semanticTests/array/copying/array_copy_different_packing.sol index 2d6198006..6e81269d8 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_different_packing.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_different_packing.sol @@ -18,6 +18,6 @@ contract c { } // ---- // test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000 -// gas irOptimized: 208074 -// gas legacy: 221769 -// gas legacyOptimized: 220611 +// gas irOptimized: 207889 +// gas legacy: 220707 +// gas legacyOptimized: 220098 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_including_array.sol b/test/libsolidity/semanticTests/array/copying/array_copy_including_array.sol index d28090277..385f2ecfb 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_including_array.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_including_array.sol @@ -35,12 +35,12 @@ contract c { } // ---- // test() -> 0x02000202 -// gas irOptimized: 4548150 -// gas legacy: 4476222 -// gas legacyOptimized: 4448113 +// gas irOptimized: 4547793 +// gas legacy: 4475396 +// gas legacyOptimized: 4447665 // storageEmpty -> 1 // clear() -> 0, 0 -// gas irOptimized: 4475134 -// gas legacy: 4408014 -// gas legacyOptimized: 4381784 +// gas irOptimized: 4474777 +// gas legacy: 4407188 +// gas legacyOptimized: 4381336 // storageEmpty -> 1 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover.sol b/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover.sol index b2af9191d..10a48a18c 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover.sol @@ -17,6 +17,6 @@ contract c { } // ---- // test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000 -// gas irOptimized: 104526 -// gas legacy: 166874 -// gas legacyOptimized: 145474 +// gas irOptimized: 100980 +// gas legacy: 158142 +// gas legacyOptimized: 141096 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_target_simple.sol b/test/libsolidity/semanticTests/array/copying/array_copy_target_simple.sol index db66a5508..a839e3bb4 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_target_simple.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_target_simple.sol @@ -18,6 +18,6 @@ contract c { } // ---- // test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0 -// gas irOptimized: 273563 -// gas legacy: 283666 -// gas legacyOptimized: 282023 +// gas irOptimized: 273372 +// gas legacy: 282604 +// gas legacyOptimized: 281510 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_target_simple_2.sol b/test/libsolidity/semanticTests/array/copying/array_copy_target_simple_2.sol index bf1e1bc1b..f9e1cbd27 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_target_simple_2.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_target_simple_2.sol @@ -18,6 +18,6 @@ contract c { } // ---- // test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00 -// gas irOptimized: 233255 -// gas legacy: 236523 -// gas legacyOptimized: 235592 +// gas irOptimized: 233118 +// gas legacy: 235697 +// gas legacyOptimized: 235193 diff --git a/test/libsolidity/semanticTests/array/copying/array_of_structs_containing_arrays_calldata_to_storage.sol b/test/libsolidity/semanticTests/array/copying/array_of_structs_containing_arrays_calldata_to_storage.sol index e3998e955..c6e6c5876 100644 --- a/test/libsolidity/semanticTests/array/copying/array_of_structs_containing_arrays_calldata_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/array_of_structs_containing_arrays_calldata_to_storage.sol @@ -23,4 +23,4 @@ contract C { // compileViaYul: true // ---- // f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1 -// gas irOptimized: 327383 +// gas irOptimized: 326771 diff --git a/test/libsolidity/semanticTests/array/copying/bytes_storage_to_storage.sol b/test/libsolidity/semanticTests/array/copying/bytes_storage_to_storage.sol index 968f637a4..38dbe52bc 100644 --- a/test/libsolidity/semanticTests/array/copying/bytes_storage_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/bytes_storage_to_storage.sol @@ -17,25 +17,25 @@ contract c { // ---- // f(uint256): 0 -> 0x20, 0x00 // f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00 -// gas irOptimized: 109219 -// gas legacy: 123948 -// gas legacyOptimized: 118948 +// gas irOptimized: 104476 +// gas legacy: 112974 +// gas legacyOptimized: 112717 // f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671 -// gas irOptimized: 123858 -// gas legacy: 140362 -// gas legacyOptimized: 135384 +// gas irOptimized: 118962 +// gas legacy: 129034 +// gas legacyOptimized: 128952 // f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000 -// gas irOptimized: 130468 -// gas legacy: 147916 -// gas legacyOptimized: 142276 +// gas irOptimized: 125419 +// gas legacy: 136234 +// gas legacyOptimized: 135643 // f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992 -// gas irOptimized: 139168 -// gas legacy: 171136 -// gas legacyOptimized: 161536 +// gas irOptimized: 129529 +// gas legacy: 148834 +// gas legacyOptimized: 148873 // f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000 // gas legacy: 59345 // gas legacyOptimized: 57279 // f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968 -// gas irOptimized: 441648 -// gas legacy: 505021 -// gas legacyOptimized: 486995 +// gas irOptimized: 421911 +// gas legacy: 459355 +// gas legacyOptimized: 461066 diff --git a/test/libsolidity/semanticTests/array/copying/memory_dyn_2d_bytes_to_storage.sol b/test/libsolidity/semanticTests/array/copying/memory_dyn_2d_bytes_to_storage.sol index 599d23c80..79882a74b 100644 --- a/test/libsolidity/semanticTests/array/copying/memory_dyn_2d_bytes_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/memory_dyn_2d_bytes_to_storage.sol @@ -18,6 +18,6 @@ contract C { } // ---- // f() -> 3 -// gas irOptimized: 128094 -// gas legacy: 130584 -// gas legacyOptimized: 129028 +// gas irOptimized: 127422 +// gas legacy: 129050 +// gas legacyOptimized: 128222 diff --git a/test/libsolidity/semanticTests/array/copying/storage_memory_nested.sol b/test/libsolidity/semanticTests/array/copying/storage_memory_nested.sol index 7c2f0e55e..9a2fbb4d9 100644 --- a/test/libsolidity/semanticTests/array/copying/storage_memory_nested.sol +++ b/test/libsolidity/semanticTests/array/copying/storage_memory_nested.sol @@ -17,6 +17,6 @@ contract C { } // ---- // f() -> 1, 2, 3, 4, 5, 6, 7 -// gas irOptimized: 205879 -// gas legacy: 212237 -// gas legacyOptimized: 211425 +// gas irOptimized: 205783 +// gas legacy: 211765 +// gas legacyOptimized: 211181 diff --git a/test/libsolidity/semanticTests/array/copying/storage_memory_nested_from_pointer.sol b/test/libsolidity/semanticTests/array/copying/storage_memory_nested_from_pointer.sol index cda6d129a..3606d7d60 100644 --- a/test/libsolidity/semanticTests/array/copying/storage_memory_nested_from_pointer.sol +++ b/test/libsolidity/semanticTests/array/copying/storage_memory_nested_from_pointer.sol @@ -18,6 +18,6 @@ contract C { } // ---- // f() -> 1, 2, 3, 4, 5, 6, 7 -// gas irOptimized: 205879 -// gas legacy: 212242 -// gas legacyOptimized: 211430 +// gas irOptimized: 205783 +// gas legacy: 211770 +// gas legacyOptimized: 211186 diff --git a/test/libsolidity/semanticTests/array/copying/storage_memory_packed_dyn.sol b/test/libsolidity/semanticTests/array/copying/storage_memory_packed_dyn.sol index 5617e2fcc..3ba5604a7 100644 --- a/test/libsolidity/semanticTests/array/copying/storage_memory_packed_dyn.sol +++ b/test/libsolidity/semanticTests/array/copying/storage_memory_packed_dyn.sol @@ -13,6 +13,6 @@ contract C { } // ---- // f() -> 2, 3, 4 -// gas irOptimized: 109702 -// gas legacy: 126129 -// gas legacyOptimized: 120622 +// gas irOptimized: 109108 +// gas legacy: 122235 +// gas legacyOptimized: 118411 diff --git a/test/libsolidity/semanticTests/array/delete/bytes_delete_element.sol b/test/libsolidity/semanticTests/array/delete/bytes_delete_element.sol index 146206ae0..fffea685a 100644 --- a/test/libsolidity/semanticTests/array/delete/bytes_delete_element.sol +++ b/test/libsolidity/semanticTests/array/delete/bytes_delete_element.sol @@ -16,6 +16,6 @@ contract c { } // ---- // test1() -> true -// gas irOptimized: 206388 -// gas legacy: 254056 -// gas legacyOptimized: 246892 +// gas irOptimized: 204782 +// gas legacy: 242256 +// gas legacyOptimized: 241192 diff --git a/test/libsolidity/semanticTests/array/dynamic_array_cleanup.sol b/test/libsolidity/semanticTests/array/dynamic_array_cleanup.sol index a04ea013a..eb950d183 100644 --- a/test/libsolidity/semanticTests/array/dynamic_array_cleanup.sol +++ b/test/libsolidity/semanticTests/array/dynamic_array_cleanup.sol @@ -14,9 +14,9 @@ contract c { // ---- // storageEmpty -> 1 // fill() -> -// gas irOptimized: 519266 -// gas legacy: 521414 -// gas legacyOptimized: 516983 +// gas irOptimized: 519017 +// gas legacy: 518936 +// gas legacyOptimized: 515555 // storageEmpty -> 0 // halfClear() -> // gas irOptimized: 113961 diff --git a/test/libsolidity/semanticTests/array/fixed_array_cleanup.sol b/test/libsolidity/semanticTests/array/fixed_array_cleanup.sol index a354cf804..b4d9a30ec 100644 --- a/test/libsolidity/semanticTests/array/fixed_array_cleanup.sol +++ b/test/libsolidity/semanticTests/array/fixed_array_cleanup.sol @@ -10,9 +10,9 @@ contract c { // ---- // storageEmpty -> 1 // fill() -> -// gas irOptimized: 465314 -// gas legacy: 471178 -// gas legacyOptimized: 467478 +// gas irOptimized: 464834 +// gas legacy: 468818 +// gas legacyOptimized: 466238 // storageEmpty -> 0 // clear() -> // gas irOptimized: 122148 diff --git a/test/libsolidity/semanticTests/array/function_array_cross_calls.sol b/test/libsolidity/semanticTests/array/function_array_cross_calls.sol index fe72091af..773e904cc 100644 --- a/test/libsolidity/semanticTests/array/function_array_cross_calls.sol +++ b/test/libsolidity/semanticTests/array/function_array_cross_calls.sol @@ -42,6 +42,6 @@ contract C { } // ---- // test() -> 5, 6, 7 -// gas irOptimized: 256288 -// gas legacy: 441556 -// gas legacyOptimized: 279321 +// gas irOptimized: 255728 +// gas legacy: 440376 +// gas legacyOptimized: 278651 diff --git a/test/libsolidity/semanticTests/array/pop/byte_array_pop_masking_long.sol b/test/libsolidity/semanticTests/array/pop/byte_array_pop_masking_long.sol index 95156f5c6..5b1a61839 100644 --- a/test/libsolidity/semanticTests/array/pop/byte_array_pop_masking_long.sol +++ b/test/libsolidity/semanticTests/array/pop/byte_array_pop_masking_long.sol @@ -9,6 +9,6 @@ contract c { } // ---- // test() -> 0x20, 33, 0x303030303030303030303030303030303030303030303030303030303030303, 0x0300000000000000000000000000000000000000000000000000000000000000 -// gas irOptimized: 107962 -// gas legacy: 125420 -// gas legacyOptimized: 122472 +// gas irOptimized: 107343 +// gas legacy: 121408 +// gas legacyOptimized: 120534 diff --git a/test/libsolidity/semanticTests/array/push/byte_array_push_transition.sol b/test/libsolidity/semanticTests/array/push/byte_array_push_transition.sol index 808d0d866..5f1fe0fac 100644 --- a/test/libsolidity/semanticTests/array/push/byte_array_push_transition.sol +++ b/test/libsolidity/semanticTests/array/push/byte_array_push_transition.sol @@ -15,6 +15,6 @@ contract c { } // ---- // test() -> 0 -// gas irOptimized: 171996 -// gas legacy: 215891 -// gas legacyOptimized: 203615 +// gas irOptimized: 167700 +// gas legacy: 206219 +// gas legacyOptimized: 197297 diff --git a/test/libsolidity/semanticTests/array/push/push_no_args_bytes.sol b/test/libsolidity/semanticTests/array/push/push_no_args_bytes.sol index 860c74337..b19ebcc73 100644 --- a/test/libsolidity/semanticTests/array/push/push_no_args_bytes.sol +++ b/test/libsolidity/semanticTests/array/push/push_no_args_bytes.sol @@ -21,9 +21,9 @@ contract C { // ---- // l() -> 0 // g(uint256): 70 -> -// gas irOptimized: 182328 -// gas legacy: 183445 -// gas legacyOptimized: 178995 +// gas irOptimized: 180849 +// gas legacy: 175185 +// gas legacyOptimized: 175005 // l() -> 70 // a(uint256): 69 -> left(69) // f() -> diff --git a/test/libsolidity/semanticTests/events/event_indexed_string.sol b/test/libsolidity/semanticTests/events/event_indexed_string.sol index a503d44f5..739619066 100644 --- a/test/libsolidity/semanticTests/events/event_indexed_string.sol +++ b/test/libsolidity/semanticTests/events/event_indexed_string.sol @@ -17,6 +17,6 @@ contract C { // ---- // deposit() -> // ~ emit E(string,uint256[4]): #0xa7fb06bb999a5eb9aff9e0779953f4e1e4ce58044936c2f51c7fb879b85c08bd, #0xe755d8cc1a8cde16a2a31160dcd8017ac32d7e2f13215b29a23cdae40a78aa81 -// gas irOptimized: 330920 -// gas legacy: 387608 -// gas legacyOptimized: 373771 +// gas irOptimized: 328856 +// gas legacy: 365828 +// gas legacyOptimized: 362251 diff --git a/test/libsolidity/semanticTests/externalContracts/base64.sol b/test/libsolidity/semanticTests/externalContracts/base64.sol index 1e366f75f..cc0331e71 100644 --- a/test/libsolidity/semanticTests/externalContracts/base64.sol +++ b/test/libsolidity/semanticTests/externalContracts/base64.sol @@ -33,9 +33,9 @@ contract test { // EVMVersion: >=constantinople // ---- // constructor() -// gas irOptimized: 406679 -// gas legacy: 737652 -// gas legacyOptimized: 527036 +// gas irOptimized: 405844 +// gas legacy: 735054 +// gas legacyOptimized: 522722 // encode_inline_asm(bytes): 0x20, 0 -> 0x20, 0 // encode_inline_asm(bytes): 0x20, 1, "f" -> 0x20, 4, "Zg==" // encode_inline_asm(bytes): 0x20, 2, "fo" -> 0x20, 4, "Zm8=" @@ -51,10 +51,10 @@ contract test { // encode_no_asm(bytes): 0x20, 5, "fooba" -> 0x20, 8, "Zm9vYmE=" // encode_no_asm(bytes): 0x20, 6, "foobar" -> 0x20, 8, "Zm9vYmFy" // encode_inline_asm_large() -// gas irOptimized: 1373025 -// gas legacy: 1672031 -// gas legacyOptimized: 1199031 +// gas irOptimized: 1322025 +// gas legacy: 1554031 +// gas legacyOptimized: 1132031 // encode_no_asm_large() -// gas irOptimized: 3257081 -// gas legacy: 4705075 -// gas legacyOptimized: 2890075 +// gas irOptimized: 3206081 +// gas legacy: 4587075 +// gas legacyOptimized: 2823075 diff --git a/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol b/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol index 8108e64f4..4f3342dea 100644 --- a/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol +++ b/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol @@ -176,35 +176,35 @@ contract DepositContract is IDepositContract, ERC165 { } // ---- // constructor() -// gas irOptimized: 1397699 -// gas legacy: 2391952 +// gas irOptimized: 1386886 +// gas legacy: 2369061 // gas legacyOptimized: 1740144 // supportsInterface(bytes4): 0x0 -> 0 // supportsInterface(bytes4): 0xffffffff00000000000000000000000000000000000000000000000000000000 -> false # defined to be false by ERC-165 # // supportsInterface(bytes4): 0x01ffc9a700000000000000000000000000000000000000000000000000000000 -> true # ERC-165 id # // supportsInterface(bytes4): 0x8564090700000000000000000000000000000000000000000000000000000000 -> true # the deposit interface id # // get_deposit_root() -> 0xd70a234731285c6804c2a4f56711ddb8c82c99740f207854891028af34e27e5e -// gas irOptimized: 116863 -// gas legacy: 151981 -// gas legacyOptimized: 124447 +// gas irOptimized: 115231 +// gas legacy: 148205 +// gas legacyOptimized: 122303 // get_deposit_count() -> 0x20, 8, 0 # TODO: check balance and logs after each deposit # // deposit(bytes,bytes,bytes,bytes32), 32 ether: 0 -> FAILURE # Empty input # // get_deposit_root() -> 0xd70a234731285c6804c2a4f56711ddb8c82c99740f207854891028af34e27e5e -// gas irOptimized: 116863 -// gas legacy: 151981 -// gas legacyOptimized: 124447 +// gas irOptimized: 115231 +// gas legacy: 148205 +// gas legacyOptimized: 122303 // get_deposit_count() -> 0x20, 8, 0 // deposit(bytes,bytes,bytes,bytes32), 1 ether: 0x80, 0xe0, 0x120, 0xaa4a8d0b7d9077248630f1a4701ae9764e42271d7f22b7838778411857fd349e, 0x30, 0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f73292, 0x67a8811c397529dac52ae1342ba58c9500000000000000000000000000000000, 0x20, 0x00f50428677c60f997aadeab24aabf7fceaef491c96a52b463ae91f95611cf71, 0x60, 0xa29d01cc8c6296a8150e515b5995390ef841dc18948aa3e79be6d7c1851b4cbb, 0x5d6ff49fa70b9c782399506a22a85193151b9b691245cebafd2063012443c132, 0x4b6c36debaedefb7b2d71b0503ffdc00150aaffd42e63358238ec888901738b8 -> # txhash: 0x7085c586686d666e8bb6e9477a0f0b09565b2060a11f1c4209d3a52295033832 # // ~ emit DepositEvent(bytes,bytes,bytes,bytes,bytes): 0xa0, 0x0100, 0x0140, 0x0180, 0x0200, 0x30, 0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f73292, 0x67a8811c397529dac52ae1342ba58c9500000000000000000000000000000000, 0x20, 0xf50428677c60f997aadeab24aabf7fceaef491c96a52b463ae91f95611cf71, 0x08, 0xca9a3b00000000000000000000000000000000000000000000000000000000, 0x60, 0xa29d01cc8c6296a8150e515b5995390ef841dc18948aa3e79be6d7c1851b4cbb, 0x5d6ff49fa70b9c782399506a22a85193151b9b691245cebafd2063012443c132, 0x4b6c36debaedefb7b2d71b0503ffdc00150aaffd42e63358238ec888901738b8, 0x08, 0x00 // get_deposit_root() -> 0x2089653123d9c721215120b6db6738ba273bbc5228ac093b1f983badcdc8a438 -// gas irOptimized: 116848 -// gas legacy: 151990 -// gas legacyOptimized: 124459 +// gas irOptimized: 115216 +// gas legacy: 148214 +// gas legacyOptimized: 122315 // get_deposit_count() -> 0x20, 8, 0x0100000000000000000000000000000000000000000000000000000000000000 // deposit(bytes,bytes,bytes,bytes32), 32 ether: 0x80, 0xe0, 0x120, 0xdbd986dc85ceb382708cf90a3500f500f0a393c5ece76963ac3ed72eccd2c301, 0x30, 0xb2ce0f79f90e7b3a113ca5783c65756f96c4b4673c2b5c1eb4efc22280259441, 0x06d601211e8866dc5b50dc48a244dd7c00000000000000000000000000000000, 0x20, 0x00344b6c73f71b11c56aba0d01b7d8ad83559f209d0a4101a515f6ad54c89771, 0x60, 0x945caaf82d18e78c033927d51f452ebcd76524497b91d7a11219cb3db6a1d369, 0x7595fc095ce489e46b2ef129591f2f6d079be4faaf345a02c5eb133c072e7c56, 0x0c6c3617eee66b4b878165c502357d49485326bc6b31bc96873f308c8f19c09d -> # txhash: 0x404d8e109822ce448e68f45216c12cb051b784d068fbe98317ab8e50c58304ac # // ~ emit DepositEvent(bytes,bytes,bytes,bytes,bytes): 0xa0, 0x0100, 0x0140, 0x0180, 0x0200, 0x30, 0xb2ce0f79f90e7b3a113ca5783c65756f96c4b4673c2b5c1eb4efc22280259441, 0x06d601211e8866dc5b50dc48a244dd7c00000000000000000000000000000000, 0x20, 0x344b6c73f71b11c56aba0d01b7d8ad83559f209d0a4101a515f6ad54c89771, 0x08, 0x40597307000000000000000000000000000000000000000000000000000000, 0x60, 0x945caaf82d18e78c033927d51f452ebcd76524497b91d7a11219cb3db6a1d369, 0x7595fc095ce489e46b2ef129591f2f6d079be4faaf345a02c5eb133c072e7c56, 0x0c6c3617eee66b4b878165c502357d49485326bc6b31bc96873f308c8f19c09d, 0x08, 0x0100000000000000000000000000000000000000000000000000000000000000 // get_deposit_root() -> 0x40255975859377d912c53aa853245ebd939bdd2b33a28e084babdcc1ed8238ee -// gas irOptimized: 116848 -// gas legacy: 151990 -// gas legacyOptimized: 124459 +// gas irOptimized: 115216 +// gas legacy: 148214 +// gas legacyOptimized: 122315 // get_deposit_count() -> 0x20, 8, 0x0200000000000000000000000000000000000000000000000000000000000000 diff --git a/test/libsolidity/semanticTests/externalContracts/prbmath_signed.sol b/test/libsolidity/semanticTests/externalContracts/prbmath_signed.sol index 8d0a99382..329aafc10 100644 --- a/test/libsolidity/semanticTests/externalContracts/prbmath_signed.sol +++ b/test/libsolidity/semanticTests/externalContracts/prbmath_signed.sol @@ -48,9 +48,9 @@ contract test { } // ---- // constructor() -// gas irOptimized: 1847920 -// gas legacy: 2430726 -// gas legacyOptimized: 1854979 +// gas irOptimized: 1841716 +// gas legacy: 2414091 +// gas legacyOptimized: 1847616 // div(int256,int256): 3141592653589793238, 88714123 -> 35412542528203691288251815328 // gas irOptimized: 22137 // gas legacy: 22767 diff --git a/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol b/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol index 2442493d7..22e52840a 100644 --- a/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol +++ b/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol @@ -48,9 +48,9 @@ contract test { } // ---- // constructor() -// gas irOptimized: 1722598 -// gas legacy: 2210160 -// gas legacyOptimized: 1734152 +// gas irOptimized: 1716771 +// gas legacy: 2193550 +// gas legacyOptimized: 1725061 // div(uint256,uint256): 3141592653589793238, 88714123 -> 35412542528203691288251815328 // gas irOptimized: 22004 // gas legacy: 22497 diff --git a/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol b/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol index a1f1d6395..3f555405d 100644 --- a/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol +++ b/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol @@ -33,10 +33,10 @@ contract test { } // ---- // constructor() -// gas irOptimized: 407075 -// gas legacy: 631753 -// gas legacyOptimized: 459425 +// gas irOptimized: 407507 +// gas legacy: 615090 +// gas legacyOptimized: 451871 // prb_pi() -> 3141592656369545286 // gas irOptimized: 57478 -// gas legacy: 101655 +// gas legacy: 100947 // gas legacyOptimized: 75735 diff --git a/test/libsolidity/semanticTests/externalContracts/snark.sol b/test/libsolidity/semanticTests/externalContracts/snark.sol index e92f95b4a..d3492a5c6 100644 --- a/test/libsolidity/semanticTests/externalContracts/snark.sol +++ b/test/libsolidity/semanticTests/externalContracts/snark.sol @@ -294,11 +294,11 @@ contract Test { // f() -> true // g() -> true // pair() -> true -// gas irOptimized: 269901 -// gas legacy: 275678 -// gas legacyOptimized: 267193 +// gas irOptimized: 269697 +// gas legacy: 275206 +// gas legacyOptimized: 266925 // verifyTx() -> true // ~ emit Verified(string): 0x20, 0x16, "Successfully verified." -// gas irOptimized: 783281 -// gas legacy: 804346 -// gas legacyOptimized: 772349 +// gas irOptimized: 782210 +// gas legacy: 801868 +// gas legacyOptimized: 770942 diff --git a/test/libsolidity/semanticTests/externalContracts/strings.sol b/test/libsolidity/semanticTests/externalContracts/strings.sol index 817f6702e..6a3013b88 100644 --- a/test/libsolidity/semanticTests/externalContracts/strings.sol +++ b/test/libsolidity/semanticTests/externalContracts/strings.sol @@ -49,9 +49,9 @@ contract test { } // ---- // constructor() -// gas irOptimized: 634316 -// gas legacy: 1065857 -// gas legacyOptimized: 725423 +// gas irOptimized: 630860 +// gas legacy: 1061957 +// gas legacyOptimized: 718937 // toSlice(string): 0x20, 11, "hello world" -> 11, 0xa0 // gas irOptimized: 22660 // gas legacy: 23190 @@ -69,6 +69,6 @@ contract test { // gas legacy: 31621 // gas legacyOptimized: 27914 // benchmark(string,bytes32): 0x40, 0x0842021, 8, "solidity" -> 0x2020 -// gas irOptimized: 1981677 -// gas legacy: 4235651 -// gas legacyOptimized: 2319622 +// gas irOptimized: 1980957 +// gas legacy: 4233999 +// gas legacyOptimized: 2318684 diff --git a/test/libsolidity/semanticTests/libraries/internal_types_in_library.sol b/test/libsolidity/semanticTests/libraries/internal_types_in_library.sol index 5aeff319c..79d53273b 100644 --- a/test/libsolidity/semanticTests/libraries/internal_types_in_library.sol +++ b/test/libsolidity/semanticTests/libraries/internal_types_in_library.sol @@ -22,6 +22,6 @@ contract Test { // ---- // library: Lib // f() -> 4, 0x11 -// gas irOptimized: 112064 -// gas legacy: 135413 -// gas legacyOptimized: 119325 +// gas irOptimized: 111560 +// gas legacy: 132935 +// gas legacyOptimized: 118023 diff --git a/test/libsolidity/semanticTests/userDefinedValueType/calldata.sol b/test/libsolidity/semanticTests/userDefinedValueType/calldata.sol index f9c2d333a..9ed64be08 100644 --- a/test/libsolidity/semanticTests/userDefinedValueType/calldata.sol +++ b/test/libsolidity/semanticTests/userDefinedValueType/calldata.sol @@ -49,13 +49,13 @@ contract C { } // ---- // test_f() -> true -// gas irOptimized: 122393 -// gas legacy: 126030 -// gas legacyOptimized: 123120 +// gas irOptimized: 122078 +// gas legacy: 125322 +// gas legacyOptimized: 122709 // test_g() -> true -// gas irOptimized: 106740 -// gas legacy: 112300 -// gas legacyOptimized: 107649 +// gas irOptimized: 106215 +// gas legacy: 111120 +// gas legacyOptimized: 106964 // addresses(uint256): 0 -> 0x18 // addresses(uint256): 1 -> 0x19 // addresses(uint256): 3 -> 0x1b