diff --git a/libyul/backends/evm/StackHelpers.h b/libyul/backends/evm/StackHelpers.h index ff8887b24a16..dae4352a02c4 100644 --- a/libyul/backends/evm/StackHelpers.h +++ b/libyul/backends/evm/StackHelpers.h @@ -377,6 +377,50 @@ class Shuffler } }; +/// A simple optimized map for mapping StackSlots to ints. +class Multiplicity +{ +public: + int& operator[](StackSlot const& _slot) + { + if (auto* p = std::get_if(&_slot)) + return m_functionCallReturnLabelSlotMultiplicity[*p]; + if (std::holds_alternative(_slot)) + return m_functionReturnLabelSlotMultiplicity; + if (auto* p = std::get_if(&_slot)) + return m_variableSlotMultiplicity[*p]; + if (auto* p = std::get_if(&_slot)) + return m_literalSlotMultiplicity[*p]; + if (auto* p = std::get_if(&_slot)) + return m_temporarySlotMultiplicity[*p]; + yulAssert(std::holds_alternative(_slot)); + return m_junkSlotMultiplicity; + } + + int at(StackSlot const& _slot) const + { + if (auto* p = std::get_if(&_slot)) + return m_functionCallReturnLabelSlotMultiplicity.at(*p); + if (std::holds_alternative(_slot)) + return m_functionReturnLabelSlotMultiplicity; + if (auto* p = std::get_if(&_slot)) + return m_variableSlotMultiplicity.at(*p); + if (auto* p = std::get_if(&_slot)) + return m_literalSlotMultiplicity.at(*p); + if (auto* p = std::get_if(&_slot)) + return m_temporarySlotMultiplicity.at(*p); + yulAssert(std::holds_alternative(_slot)); + return m_junkSlotMultiplicity; + } + +private: + std::map m_functionCallReturnLabelSlotMultiplicity; + int m_functionReturnLabelSlotMultiplicity = 0; + std::map m_variableSlotMultiplicity; + std::map m_literalSlotMultiplicity; + std::map m_temporarySlotMultiplicity; + int m_junkSlotMultiplicity = 0; +}; /// Transforms @a _currentStack to @a _targetStack, invoking the provided shuffling operations. /// Modifies @a _currentStack itself after each invocation of the shuffling operations. @@ -395,7 +439,7 @@ void createStackLayout(Stack& _currentStack, Stack const& _targetStack, Swap _sw Swap swapCallback; PushOrDup pushOrDupCallback; Pop popCallback; - std::map multiplicity; + Multiplicity multiplicity; ShuffleOperations( Stack& _currentStack, Stack const& _targetStack, diff --git a/libyul/backends/evm/StackLayoutGenerator.cpp b/libyul/backends/evm/StackLayoutGenerator.cpp index ddb1b6379339..2d5cdde87fd0 100644 --- a/libyul/backends/evm/StackLayoutGenerator.cpp +++ b/libyul/backends/evm/StackLayoutGenerator.cpp @@ -172,7 +172,7 @@ Stack createIdealLayout(Stack const& _operationOutput, Stack const& _post, Calla vector>& layout; Stack const& post; std::set outputs; - std::map multiplicity; + Multiplicity multiplicity; Callable generateSlotOnTheFly; ShuffleOperations( vector>& _layout,