11#pragma once
22
33#include < libyul/backends/evm/ssa/LivenessAnalysis.h>
4+ #include < libyul/backends/evm/ssa/Stack.h>
45
56#include < range/v3/algorithm/equal.hpp>
67#include < range/v3/algorithm/find.hpp>
@@ -32,14 +33,14 @@ std::map<Slot, size_t> histogram(Slots const& _slots)
3233}
3334}
3435
35- template <typename Stack , size_t ReachableStackDepth=16 >
36+ template <StackManipulationCallbackConcept Callback , size_t ReachableStackDepth=16 >
3637class OperationForwardShuffler
3738{
3839 using Slot = StackSlot;
3940
4041public:
4142 static void shuffle (
42- Stack& _stack,
43+ Stack<Callback> & _stack,
4344 std::vector<Slot> const & _args,
4445 LivenessAnalysis::LivenessData const & _liveOut,
4546 bool _generateJunk
@@ -54,7 +55,7 @@ class OperationForwardShuffler
5455 }
5556
5657private:
57- static std::ptrdiff_t loss (Stack::Data const & _stackData, std::vector<Slot> const & _args, LivenessAnalysis::LivenessData const & _liveOut)
58+ static std::ptrdiff_t loss (Stack<Callback> ::Data const & _stackData, std::vector<Slot> const & _args, LivenessAnalysis::LivenessData const & _liveOut)
5859 {
5960 std::ptrdiff_t result = 0 ;
6061
@@ -81,7 +82,7 @@ class OperationForwardShuffler
8182
8283 struct StackStats
8384 {
84- StackStats (Stack const & _stack, size_t _argsRegionSize)
85+ StackStats (Stack<Callback> const & _stack, size_t _argsRegionSize)
8586 {
8687 histogramTail = detail::histogram (_stack.data () | ranges::views::reverse | ranges::views::drop (_argsRegionSize));
8788 histogram = histogramTail;
@@ -121,7 +122,7 @@ class OperationForwardShuffler
121122
122123 struct Ops
123124 {
124- Ops (Stack const & _stack, std::vector<Slot> const & _args, LivenessAnalysis::LivenessData const & _liveOut):
125+ Ops (Stack<Callback> const & _stack, std::vector<Slot> const & _args, LivenessAnalysis::LivenessData const & _liveOut):
125126 stackStats (_stack, _args.size()),
126127 targetMinCounts (detail::histogram(_args)),
127128 stack (_stack),
@@ -201,15 +202,15 @@ class OperationForwardShuffler
201202
202203 StackStats stackStats;
203204 std::map<Slot, size_t > targetMinCounts;
204- Stack const & stack;
205+ Stack<Callback> const & stack;
205206 std::vector<Slot> const & args;
206207 LivenessAnalysis::LivenessData const & liveOut;
207208 };
208209
209210 // If dupping an ideal slot causes a slot that will still be required to become unreachable, then dup
210211 // the latter slot first.
211212 // @returns true, if it performed a dup.
212- static bool dupDeepSlotIfRequired (Ops const & _ops, Stack& _stack, bool const _generateJunk)
213+ static bool dupDeepSlotIfRequired (Ops const & _ops, Stack<Callback> & _stack, bool const _generateJunk)
213214 {
214215 // Check if the stack is large enough for anything to potentially become unreachable.
215216 if (_stack.size () < ReachableStackDepth - 1 )
@@ -300,7 +301,7 @@ class OperationForwardShuffler
300301 }
301302
302303 static bool shuffleStep (
303- Stack& _stack,
304+ Stack<Callback> & _stack,
304305 std::vector<Slot> const & _args,
305306 LivenessAnalysis::LivenessData const & _liveOut,
306307 bool const _generateJunk
@@ -312,14 +313,14 @@ class OperationForwardShuffler
312313 if (ops.argsRegionIsCorrect ())
313314 {
314315 // Check if any of the args are required in the tail and not there yet
315- bool const argRequiredInTail = [&]
316+ bool const needMoreOfAnyArg = [&]
316317 {
317318 for (auto const & arg: ops.args )
318319 if (ops.stackStats .totalCount (arg) < ops.targetMinCount (arg))
319320 return true ;
320321 return false ;
321322 }();
322- if (argRequiredInTail )
323+ if (needMoreOfAnyArg )
323324 {
324325 // todo whatever we have to dup might not be reachable, check the implications of this in the algorithm:
325326 // we could go stack-too-deep or we could try to compress the args (which might end in a loop?)
0 commit comments