29
29
#include < libsolutil/StackTooDeepString.h>
30
30
31
31
#include < range/v3/view/reverse.hpp>
32
+ #include < utility>
32
33
33
34
using namespace solidity ;
34
35
using namespace solidity ::evmasm;
@@ -57,9 +58,9 @@ std::vector<AssemblyItem> CommonSubexpressionEliminator::getOptimizedItems()
57
58
if (!m_state.stackElements ().empty ())
58
59
minHeight = std::min (minHeight, m_state.stackElements ().begin ()->first );
59
60
for (int height = minHeight; height <= m_initialState.stackHeight (); ++height)
60
- initialStackContents[height] = m_initialState.stackElement (height, SourceLocation ());
61
+ initialStackContents[height] = m_initialState.stackElement (height, langutil::DebugData::create ());
61
62
for (int height = minHeight; height <= m_state.stackHeight (); ++height)
62
- targetStackContents[height] = m_state.stackElement (height, SourceLocation ());
63
+ targetStackContents[height] = m_state.stackElement (height, langutil::DebugData::create ());
63
64
64
65
AssemblyItems items = CSECodeGenerator (m_state.expressionClasses (), m_storeOperations).generateCode (
65
66
m_initialState.sequenceNumber (),
@@ -87,36 +88,37 @@ void CommonSubexpressionEliminator::optimizeBreakingItem()
87
88
88
89
ExpressionClasses& classes = m_state.expressionClasses ();
89
90
SourceLocation const & itemLocation = m_breakingItem->location ();
91
+ langutil::DebugData::ConstPtr debugData{langutil::DebugData::create (itemLocation)};
90
92
if (*m_breakingItem == AssemblyItem (Instruction::JUMPI))
91
93
{
92
94
AssemblyItem::JumpType jumpType = m_breakingItem->getJumpType ();
93
95
94
- Id condition = m_state.stackElement (m_state.stackHeight () - 1 , itemLocation );
96
+ Id condition = m_state.stackElement (m_state.stackHeight () - 1 , debugData );
95
97
if (classes.knownNonZero (condition))
96
98
{
97
- feedItem (AssemblyItem (Instruction::SWAP1, itemLocation ), true );
98
- feedItem (AssemblyItem (Instruction::POP, itemLocation ), true );
99
+ feedItem (AssemblyItem (Instruction::SWAP1, debugData ), true );
100
+ feedItem (AssemblyItem (Instruction::POP, debugData ), true );
99
101
100
- AssemblyItem item (Instruction::JUMP, itemLocation );
102
+ AssemblyItem item (Instruction::JUMP, debugData );
101
103
item.setJumpType (jumpType);
102
104
m_breakingItem = classes.storeItem (item);
103
105
}
104
106
else if (classes.knownZero (condition))
105
107
{
106
- AssemblyItem it (Instruction::POP, itemLocation );
108
+ AssemblyItem it (Instruction::POP, debugData );
107
109
feedItem (it, true );
108
110
feedItem (it, true );
109
111
m_breakingItem = nullptr ;
110
112
}
111
113
}
112
114
else if (*m_breakingItem == AssemblyItem (Instruction::RETURN))
113
115
{
114
- Id size = m_state.stackElement (m_state.stackHeight () - 1 , itemLocation );
116
+ Id size = m_state.stackElement (m_state.stackHeight () - 1 , debugData );
115
117
if (classes.knownZero (size))
116
118
{
117
- feedItem (AssemblyItem (Instruction::POP, itemLocation ), true );
118
- feedItem (AssemblyItem (Instruction::POP, itemLocation ), true );
119
- AssemblyItem item (Instruction::STOP, itemLocation );
119
+ feedItem (AssemblyItem (Instruction::POP, debugData ), true );
120
+ feedItem (AssemblyItem (Instruction::POP, debugData ), true );
121
+ AssemblyItem item (Instruction::STOP, debugData );
120
122
m_breakingItem = classes.storeItem (item);
121
123
}
122
124
}
@@ -181,16 +183,16 @@ AssemblyItems CSECodeGenerator::generateCode(
181
183
assertThrow (!m_classPositions[targetItem.second ].empty (), OptimizerException, " " );
182
184
if (m_classPositions[targetItem.second ].count (targetItem.first ))
183
185
continue ;
184
- SourceLocation sourceLocation ;
186
+ langutil::DebugData::ConstPtr debugData ;
185
187
if (m_expressionClasses.representative (targetItem.second ).item )
186
- sourceLocation = m_expressionClasses.representative (targetItem.second ).item ->location ();
188
+ debugData = m_expressionClasses.representative (targetItem.second ).item ->debugData ();
187
189
int position = classElementPosition (targetItem.second );
188
190
if (position < targetItem.first )
189
191
// it is already at its target, we need another copy
190
- appendDup (position, sourceLocation );
192
+ appendDup (position, debugData );
191
193
else
192
- appendOrRemoveSwap (position, sourceLocation );
193
- appendOrRemoveSwap (targetItem.first , sourceLocation );
194
+ appendOrRemoveSwap (position, debugData );
195
+ appendOrRemoveSwap (targetItem.first , debugData );
194
196
}
195
197
196
198
// remove surplus elements
@@ -263,7 +265,7 @@ void CSECodeGenerator::addDependencies(Id _c)
263
265
case Instruction::KECCAK256:
264
266
{
265
267
Id length = expr.arguments .at (1 );
266
- AssemblyItem offsetInstr (Instruction::SUB, expr.item ->location ());
268
+ AssemblyItem offsetInstr (Instruction::SUB, expr.item ->debugData ());
267
269
Id offsetToStart = m_expressionClasses.find (offsetInstr, {slot, slotToLoadFrom});
268
270
u256 const * o = m_expressionClasses.knownConstant (offsetToStart);
269
271
u256 const * l = m_expressionClasses.knownConstant (length);
@@ -334,50 +336,50 @@ void CSECodeGenerator::generateClassElement(Id _c, bool _allowSequenced)
334
336
for (Id arg: arguments | ranges::views::reverse)
335
337
generateClassElement (arg);
336
338
337
- SourceLocation const & itemLocation = expr.item ->location ();
339
+ langutil::DebugData::ConstPtr itemDebugData = expr.item ->debugData ();
338
340
// The arguments are somewhere on the stack now, so it remains to move them at the correct place.
339
341
// This is quite difficult as sometimes, the values also have to removed in this process
340
342
// (if canBeRemoved() returns true) and the two arguments can be equal. For now, this is
341
343
// implemented for every single case for combinations of up to two arguments manually.
342
344
if (arguments.size () == 1 )
343
345
{
344
346
if (canBeRemoved (arguments[0 ], _c))
345
- appendOrRemoveSwap (classElementPosition (arguments[0 ]), itemLocation );
347
+ appendOrRemoveSwap (classElementPosition (arguments[0 ]), itemDebugData );
346
348
else
347
- appendDup (classElementPosition (arguments[0 ]), itemLocation );
349
+ appendDup (classElementPosition (arguments[0 ]), itemDebugData );
348
350
}
349
351
else if (arguments.size () == 2 )
350
352
{
351
353
if (canBeRemoved (arguments[1 ], _c))
352
354
{
353
- appendOrRemoveSwap (classElementPosition (arguments[1 ]), itemLocation );
355
+ appendOrRemoveSwap (classElementPosition (arguments[1 ]), itemDebugData );
354
356
if (arguments[0 ] == arguments[1 ])
355
- appendDup (m_stackHeight, itemLocation );
357
+ appendDup (m_stackHeight, itemDebugData );
356
358
else if (canBeRemoved (arguments[0 ], _c))
357
359
{
358
- appendOrRemoveSwap (m_stackHeight - 1 , itemLocation );
359
- appendOrRemoveSwap (classElementPosition (arguments[0 ]), itemLocation );
360
+ appendOrRemoveSwap (m_stackHeight - 1 , itemDebugData );
361
+ appendOrRemoveSwap (classElementPosition (arguments[0 ]), itemDebugData );
360
362
}
361
363
else
362
- appendDup (classElementPosition (arguments[0 ]), itemLocation );
364
+ appendDup (classElementPosition (arguments[0 ]), itemDebugData );
363
365
}
364
366
else
365
367
{
366
368
if (arguments[0 ] == arguments[1 ])
367
369
{
368
- appendDup (classElementPosition (arguments[0 ]), itemLocation );
369
- appendDup (m_stackHeight, itemLocation );
370
+ appendDup (classElementPosition (arguments[0 ]), itemDebugData );
371
+ appendDup (m_stackHeight, itemDebugData );
370
372
}
371
373
else if (canBeRemoved (arguments[0 ], _c))
372
374
{
373
- appendOrRemoveSwap (classElementPosition (arguments[0 ]), itemLocation );
374
- appendDup (classElementPosition (arguments[1 ]), itemLocation );
375
- appendOrRemoveSwap (m_stackHeight - 1 , itemLocation );
375
+ appendOrRemoveSwap (classElementPosition (arguments[0 ]), itemDebugData );
376
+ appendDup (classElementPosition (arguments[1 ]), itemDebugData );
377
+ appendOrRemoveSwap (m_stackHeight - 1 , itemDebugData );
376
378
}
377
379
else
378
380
{
379
- appendDup (classElementPosition (arguments[1 ]), itemLocation );
380
- appendDup (classElementPosition (arguments[0 ]), itemLocation );
381
+ appendDup (classElementPosition (arguments[1 ]), itemDebugData );
382
+ appendDup (classElementPosition (arguments[0 ]), itemDebugData );
381
383
}
382
384
}
383
385
}
@@ -398,7 +400,7 @@ void CSECodeGenerator::generateClassElement(Id _c, bool _allowSequenced)
398
400
!m_generatedItems.empty () &&
399
401
m_generatedItems.back () == AssemblyItem (Instruction::SWAP1))
400
402
// this will not append a swap but remove the one that is already there
401
- appendOrRemoveSwap (m_stackHeight - 1 , itemLocation );
403
+ appendOrRemoveSwap (m_stackHeight - 1 , itemDebugData );
402
404
for (size_t i = 0 ; i < arguments.size (); ++i)
403
405
{
404
406
m_classPositions[m_stack[m_stackHeight - static_cast <int >(i)]].erase (m_stackHeight - static_cast <int >(i));
@@ -467,26 +469,26 @@ bool CSECodeGenerator::removeStackTopIfPossible()
467
469
return true ;
468
470
}
469
471
470
- void CSECodeGenerator::appendDup (int _fromPosition, SourceLocation const & _location )
472
+ void CSECodeGenerator::appendDup (int _fromPosition, langutil::DebugData::ConstPtr _debugData )
471
473
{
472
474
assertThrow (_fromPosition != c_invalidPosition, OptimizerException, " " );
473
475
int instructionNum = 1 + m_stackHeight - _fromPosition;
474
476
assertThrow (instructionNum <= 16 , StackTooDeepException, util::stackTooDeepString);
475
477
assertThrow (1 <= instructionNum, OptimizerException, " Invalid stack access." );
476
- appendItem (AssemblyItem (dupInstruction (static_cast <unsigned >(instructionNum)), _location ));
478
+ appendItem (AssemblyItem (dupInstruction (static_cast <unsigned >(instructionNum)), std::move (_debugData) ));
477
479
m_stack[m_stackHeight] = m_stack[_fromPosition];
478
480
m_classPositions[m_stack[m_stackHeight]].insert (m_stackHeight);
479
481
}
480
482
481
- void CSECodeGenerator::appendOrRemoveSwap (int _fromPosition, SourceLocation const & _location )
483
+ void CSECodeGenerator::appendOrRemoveSwap (int _fromPosition, langutil::DebugData::ConstPtr _debugData )
482
484
{
483
485
assertThrow (_fromPosition != c_invalidPosition, OptimizerException, " " );
484
486
if (_fromPosition == m_stackHeight)
485
487
return ;
486
488
int instructionNum = m_stackHeight - _fromPosition;
487
489
assertThrow (instructionNum <= 16 , StackTooDeepException, util::stackTooDeepString);
488
490
assertThrow (1 <= instructionNum, OptimizerException, " Invalid stack access." );
489
- appendItem (AssemblyItem (swapInstruction (static_cast <unsigned >(instructionNum)), _location ));
491
+ appendItem (AssemblyItem (swapInstruction (static_cast <unsigned >(instructionNum)), std::move (_debugData) ));
490
492
491
493
if (m_stack[m_stackHeight] != m_stack[_fromPosition])
492
494
{
0 commit comments