From 3fe52d98694b1a27fd2736619fc5c1bce7d18156 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 7 Sep 2021 15:04:12 +0200 Subject: [PATCH] Run the optimizer only once. --- Changelog.md | 1 + libevmasm/Assembly.cpp | 10 +++++++--- libevmasm/Assembly.h | 6 +++++- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/Changelog.md b/Changelog.md index 5bbd686a3..fc61a1b19 100644 --- a/Changelog.md +++ b/Changelog.md @@ -15,6 +15,7 @@ Compiler Features: Bugfixes: + * Opcode Optimizer: Prevent the optimizer from running multiple times to avoid potential bytecode differences for referenced code. * Name Resolver: Fix that when importing an aliased symbol using ``import {AliasedName} from "a.sol"`` it would use the original name of the symbol and not the aliased one. * SMTChecker: Fix false negative caused by ``push`` on storage array references returned by internal functions. * SMTChecker: Fix false positive in external calls from constructors. diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index dad9635d7..ef465cf35 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -409,18 +409,21 @@ Assembly& Assembly::optimise(OptimiserSettings const& _settings) return *this; } -map Assembly::optimiseInternal( +map const& Assembly::optimiseInternal( OptimiserSettings const& _settings, std::set _tagsReferencedFromOutside ) { + if (m_tagReplacements) + return *m_tagReplacements; + // Run optimisation for sub-assemblies. for (size_t subId = 0; subId < m_subs.size(); ++subId) { OptimiserSettings settings = _settings; // Disable creation mode for sub-assemblies. settings.isCreation = false; - map subTagReplacements = m_subs[subId]->optimiseInternal( + map const& subTagReplacements = m_subs[subId]->optimiseInternal( settings, JumpdestRemover::referencedTags(m_items, subId) ); @@ -546,7 +549,8 @@ map Assembly::optimiseInternal( *this ); - return tagReplacements; + m_tagReplacements = move(tagReplacements); + return *m_tagReplacements; } LinkerObject const& Assembly::assemble() const diff --git a/libevmasm/Assembly.h b/libevmasm/Assembly.h index 4a0779ef7..732aa14a1 100644 --- a/libevmasm/Assembly.h +++ b/libevmasm/Assembly.h @@ -165,7 +165,7 @@ protected: /// Does the same operations as @a optimise, but should only be applied to a sub and /// returns the replaced tags. Also takes an argument containing the tags of this assembly /// that are referenced in a super-assembly. - std::map optimiseInternal(OptimiserSettings const& _settings, std::set _tagsReferencedFromOutside); + std::map const& optimiseInternal(OptimiserSettings const& _settings, std::set _tagsReferencedFromOutside); unsigned bytesRequired(unsigned subTagSize) const; @@ -210,6 +210,10 @@ protected: /// This map is used only for sub-assemblies which are not direct sub-assemblies (where path is having more than one value). std::map, size_t> m_subPaths; + /// Contains the tag replacements relevant for super-assemblies. + /// If set, it means the optimizer has run and we will not run it again. + std::optional> m_tagReplacements; + mutable LinkerObject m_assembledObject; mutable std::vector m_tagPositionsInBytecode;