Merge pull request #260 from chriseth/stackrotation

Simplify and optimise stack rotation.
This commit is contained in:
chriseth 2015-11-30 20:40:41 +01:00
commit 8cbe99fd1f
2 changed files with 27 additions and 8 deletions

View File

@ -695,18 +695,31 @@ void CompilerUtils::copyToStackTop(unsigned _stackDepth, unsigned _itemSize)
void CompilerUtils::moveToStackTop(unsigned _stackDepth, unsigned _itemSize)
{
solAssert(_stackDepth <= 15, "Stack too deep, try removing local variables.");
for (unsigned j = 0; j < _itemSize; ++j)
for (unsigned i = 0; i < _stackDepth + _itemSize - 1; ++i)
m_context << eth::swapInstruction(1 + i);
moveIntoStack(_itemSize, _stackDepth);
}
void CompilerUtils::moveIntoStack(unsigned _stackDepth, unsigned _itemSize)
{
solAssert(_stackDepth <= 16, "Stack too deep, try removing local variables.");
for (unsigned j = 0; j < _itemSize; ++j)
for (unsigned i = _stackDepth; i > 0; --i)
m_context << eth::swapInstruction(i + _itemSize - 1);
if (_stackDepth <= _itemSize)
for (unsigned i = 0; i < _stackDepth; ++i)
rotateStackDown(_stackDepth + _itemSize);
else
for (unsigned i = 0; i < _itemSize; ++i)
rotateStackUp(_stackDepth + _itemSize);
}
void CompilerUtils::rotateStackUp(unsigned _items)
{
solAssert(_items - 1 <= 16, "Stack too deep, try removing local variables.");
for (unsigned i = 1; i < _items; ++i)
m_context << eth::swapInstruction(_items - i);
}
void CompilerUtils::rotateStackDown(unsigned _items)
{
solAssert(_items - 1 <= 16, "Stack too deep, try removing local variables.");
for (unsigned i = 1; i < _items; ++i)
m_context << eth::swapInstruction(i);
}
void CompilerUtils::popStackElement(Type const& _type)

View File

@ -134,6 +134,12 @@ public:
void moveToStackTop(unsigned _stackDepth, unsigned _itemSize = 1);
/// Moves @a _itemSize elements past @a _stackDepth other stack elements
void moveIntoStack(unsigned _stackDepth, unsigned _itemSize = 1);
/// Rotates the topmost @a _items items on the stack, such that the previously topmost element
/// is bottom-most.
void rotateStackUp(unsigned _items);
/// Rotates the topmost @a _items items on the stack, such that the previously bottom-most element
/// is now topmost.
void rotateStackDown(unsigned _items);
/// Removes the current value from the top of the stack.
void popStackElement(Type const& _type);
/// Removes element from the top of the stack _amount times.