From 1034ccb861b7e0255144c4b6dad08a8d606158e6 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Wed, 26 Feb 2025 19:49:07 +0100 Subject: [PATCH] Remove source locations on Yul optimizer function deduplication. --- libyul/AST.h | 12 ++ libyul/CMakeLists.txt | 1 + .../optimiser/EquivalentFunctionCombiner.cpp | 11 ++ libyul/optimiser/EquivalentFunctionCombiner.h | 1 + libyul/optimiser/SourceLocationRemover.h | 117 ++++++++++++++++++ 5 files changed, 142 insertions(+) create mode 100644 libyul/optimiser/SourceLocationRemover.h diff --git a/libyul/AST.h b/libyul/AST.h index d5988ee05386..a074ceeaf60a 100644 --- a/libyul/AST.h +++ b/libyul/AST.h @@ -154,12 +154,24 @@ template inline langutil::DebugData::ConstPtr debugDataOf(T const& _no return _node.debugData; } +/// Extracts the debug data from a Yul node. +template inline void setDebugData(T& _node, langutil::DebugData::ConstPtr _debugData) +{ + _node.debugData = std::move(_debugData); +} + /// Extracts the debug data from a Yul node. template inline langutil::DebugData::ConstPtr debugDataOf(std::variant const& _node) { return std::visit([](auto const& _arg) { return debugDataOf(_arg); }, _node); } +/// Extracts the debug data from a Yul node. +template inline void setDebugData(std::variant& _node, langutil::DebugData::ConstPtr _debugData) +{ + return std::visit([&](auto& _arg) { setDebugData(_arg, _debugData); }, _node); +} + inline bool hasDefaultCase(Switch const& _switch) { return std::any_of( diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt index cc4c5051c4bd..0499eb2bd84a 100644 --- a/libyul/CMakeLists.txt +++ b/libyul/CMakeLists.txt @@ -178,6 +178,7 @@ add_library(yul optimiser/Semantics.h optimiser/SimplificationRules.cpp optimiser/SimplificationRules.h + optimiser/SourceLocationRemover.h optimiser/StackCompressor.cpp optimiser/StackCompressor.h optimiser/StackLimitEvader.cpp diff --git a/libyul/optimiser/EquivalentFunctionCombiner.cpp b/libyul/optimiser/EquivalentFunctionCombiner.cpp index bbbf039d56ed..d9c714d4563c 100644 --- a/libyul/optimiser/EquivalentFunctionCombiner.cpp +++ b/libyul/optimiser/EquivalentFunctionCombiner.cpp @@ -20,8 +20,10 @@ */ #include +#include #include #include +#include using namespace solidity; using namespace solidity::yul; @@ -31,6 +33,15 @@ void EquivalentFunctionCombiner::run(OptimiserStepContext&, Block& _ast) EquivalentFunctionCombiner{EquivalentFunctionDetector::run(_ast)}(_ast); } +void EquivalentFunctionCombiner::operator()(FunctionDefinition& _functionDefinition) +{ + for (auto* functionDefinition: m_duplicates | ranges::views::values) + if (&_functionDefinition == functionDefinition) + SourceLocationRemover{}(_functionDefinition); + ASTModifier::operator()(_functionDefinition); +} + + void EquivalentFunctionCombiner::operator()(FunctionCall& _funCall) { if (!isBuiltinFunctionCall(_funCall)) diff --git a/libyul/optimiser/EquivalentFunctionCombiner.h b/libyul/optimiser/EquivalentFunctionCombiner.h index 627dcb3ff4fd..e40c91c7d705 100644 --- a/libyul/optimiser/EquivalentFunctionCombiner.h +++ b/libyul/optimiser/EquivalentFunctionCombiner.h @@ -44,6 +44,7 @@ class EquivalentFunctionCombiner: public ASTModifier using ASTModifier::operator(); void operator()(FunctionCall& _funCall) override; + void operator()(FunctionDefinition& _funCall) override; private: EquivalentFunctionCombiner(std::map _duplicates): m_duplicates(std::move(_duplicates)) {} diff --git a/libyul/optimiser/SourceLocationRemover.h b/libyul/optimiser/SourceLocationRemover.h new file mode 100644 index 000000000000..fb4494fb41e8 --- /dev/null +++ b/libyul/optimiser/SourceLocationRemover.h @@ -0,0 +1,117 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 +#pragma once + +#include +#include +#include + +namespace solidity::yul +{ +class SourceLocationRemover: public ASTModifier +{ +public: + void operator()(Literal& _literal) override + { + resetDebugData(_literal); + ASTModifier::operator()(_literal); + } + void operator()(Identifier& _identifier) override + { + resetDebugData(_identifier); + ASTModifier::operator()(_identifier); + } + void operator()(FunctionCall& _funCall) override + { + resetDebugData(_funCall.functionName); + resetDebugData(_funCall); + ASTModifier::operator()(_funCall); + } + void operator()(ExpressionStatement& _statement) override + { + resetDebugData(_statement); + ASTModifier::operator()(_statement); + } + void operator()(Assignment& _assignment) override + { + resetDebugData(_assignment); + ASTModifier::operator()(_assignment); + } + void operator()(VariableDeclaration& _varDecl) override + { + resetDebugData(_varDecl); + ASTModifier::operator()(_varDecl); + } + void operator()(If& _if) override + { + resetDebugData(_if); + ASTModifier::operator()(_if); + } + void operator()(Switch& _switch) override + { + resetDebugData(_switch); + ASTModifier::operator()(_switch); + } + void operator()(FunctionDefinition& _functionDefinition) override + { + resetDebugData(_functionDefinition); + ASTModifier::operator()(_functionDefinition); + } + void operator()(ForLoop& _forLoop) override + { + resetDebugData(_forLoop); + ASTModifier::operator()(_forLoop); + } + void operator()(Break& _break) override + { + resetDebugData(_break); + ASTModifier::operator()(_break); + } + void operator()(Continue& _continue) override + { + resetDebugData(_continue); + ASTModifier::operator()(_continue); + } + void operator()(Leave& _leaveStatement) override + { + resetDebugData(_leaveStatement); + ASTModifier::operator()(_leaveStatement); + } + void operator()(Block& _block) override + { + resetDebugData(_block); + ASTModifier::operator()(_block); + } + void visit(Statement& _st) override + { + resetDebugData(_st); + ASTModifier::visit(_st); + } + void visit(Expression& _e) override + { + resetDebugData(_e); + ASTModifier::visit(_e); + } + template + void resetDebugData(T& _node) + { + setDebugData(_node, {}); + } + +}; +}