Browse Source

Remove stack sequence id.

cl-refactor
chriseth 10 years ago
parent
commit
442a34c9b0
  1. 63
      libevmcore/CommonSubexpressionEliminator.cpp
  2. 12
      libevmcore/CommonSubexpressionEliminator.h

63
libevmcore/CommonSubexpressionEliminator.cpp

@ -36,16 +36,11 @@ vector<AssemblyItem> CommonSubexpressionEliminator::getOptimizedItems()
map<int, ExpressionClasses::Id> targetStackContents; map<int, ExpressionClasses::Id> targetStackContents;
int minHeight = m_stackHeight + 1; int minHeight = m_stackHeight + 1;
if (!m_stackElements.empty()) if (!m_stackElements.empty())
minHeight = min(minHeight, m_stackElements.begin()->first.first); minHeight = min(minHeight, m_stackElements.begin()->first);
for (int height = minHeight; height <= max(0, m_stackHeight); ++height) for (int height = minHeight; height <= 0; ++height)
{ initialStackContents[height] = initialStackElement(height);
// make sure it is created for (int height = minHeight; height <= m_stackHeight; ++height)
ExpressionClasses::Id c = getStackElement(height); targetStackContents[height] = stackElement(height);
if (height <= 0)
initialStackContents[height] = m_expressionClasses.find(AssemblyItem(dupInstruction(1 - height)));
if (height <= m_stackHeight)
targetStackContents[height] = c;
}
// Debug info: // Debug info:
//stream(cout, currentStackContents, targetStackContents); //stream(cout, currentStackContents, targetStackContents);
@ -74,7 +69,7 @@ ostream& CommonSubexpressionEliminator::stream(
_out << "Stack elements: " << endl; _out << "Stack elements: " << endl;
for (auto const& it: m_stackElements) for (auto const& it: m_stackElements)
{ {
_out << " " << dec << it.first.first << "(" << it.first.second << ") = "; _out << " " << dec << it.first << " = ";
streamExpressionClass(_out, it.second); streamExpressionClass(_out, it.second);
} }
_out << "Equivalence classes: " << endl; _out << "Equivalence classes: " << endl;
@ -112,7 +107,7 @@ void CommonSubexpressionEliminator::feedItem(AssemblyItem const& _item)
if (SemanticInformation::isDupInstruction(_item)) if (SemanticInformation::isDupInstruction(_item))
setStackElement( setStackElement(
m_stackHeight + 1, m_stackHeight + 1,
getStackElement(m_stackHeight - int(instruction) + int(Instruction::DUP1)) stackElement(m_stackHeight - int(instruction) + int(Instruction::DUP1))
); );
else if (SemanticInformation::isSwapInstruction(_item)) else if (SemanticInformation::isSwapInstruction(_item))
swapStackElements( swapStackElements(
@ -123,7 +118,7 @@ void CommonSubexpressionEliminator::feedItem(AssemblyItem const& _item)
{ {
vector<ExpressionClasses::Id> arguments(info.args); vector<ExpressionClasses::Id> arguments(info.args);
for (int i = 0; i < info.args; ++i) for (int i = 0; i < info.args; ++i)
arguments[i] = getStackElement(m_stackHeight - i); arguments[i] = stackElement(m_stackHeight - i);
setStackElement(m_stackHeight + _item.deposit(), m_expressionClasses.find(_item, arguments)); setStackElement(m_stackHeight + _item.deposit(), m_expressionClasses.find(_item, arguments));
} }
m_stackHeight += _item.deposit(); m_stackHeight += _item.deposit();
@ -132,48 +127,34 @@ void CommonSubexpressionEliminator::feedItem(AssemblyItem const& _item)
void CommonSubexpressionEliminator::setStackElement(int _stackHeight, ExpressionClasses::Id _class) void CommonSubexpressionEliminator::setStackElement(int _stackHeight, ExpressionClasses::Id _class)
{ {
unsigned nextSequence = getNextStackElementSequence(_stackHeight); m_stackElements[_stackHeight] = _class;
m_stackElements[make_pair(_stackHeight, nextSequence)] = _class;
} }
void CommonSubexpressionEliminator::swapStackElements(int _stackHeightA, int _stackHeightB) void CommonSubexpressionEliminator::swapStackElements(int _stackHeightA, int _stackHeightB)
{ {
if (_stackHeightA == _stackHeightB) if (_stackHeightA == _stackHeightB)
BOOST_THROW_EXCEPTION(OptimizerException() << errinfo_comment("Swap on same stack elements.")); BOOST_THROW_EXCEPTION(OptimizerException() << errinfo_comment("Swap on same stack elements."));
ExpressionClasses::Id classA = getStackElement(_stackHeightA); // ensure they are created
ExpressionClasses::Id classB = getStackElement(_stackHeightB); stackElement(_stackHeightA);
stackElement(_stackHeightB);
unsigned nextSequenceA = getNextStackElementSequence(_stackHeightA); swap(m_stackElements[_stackHeightA], m_stackElements[_stackHeightB]);
unsigned nextSequenceB = getNextStackElementSequence(_stackHeightB);
m_stackElements[make_pair(_stackHeightA, nextSequenceA)] = classB;
m_stackElements[make_pair(_stackHeightB, nextSequenceB)] = classA;
} }
ExpressionClasses::Id CommonSubexpressionEliminator::getStackElement(int _stackHeight) ExpressionClasses::Id CommonSubexpressionEliminator::stackElement(int _stackHeight)
{ {
// retrieve class by last sequence number if (m_stackElements.count(_stackHeight))
unsigned nextSequence = getNextStackElementSequence(_stackHeight); return m_stackElements.at(_stackHeight);
if (nextSequence > 0)
return m_stackElements[make_pair(_stackHeight, nextSequence - 1)];
// Stack element not found (not assigned yet), create new equivalence class. // Stack element not found (not assigned yet), create new equivalence class.
assertThrow(_stackHeight <= 0, OptimizerException, "Stack element accessed before assignment."); return m_stackElements[_stackHeight] = initialStackElement(_stackHeight);
assertThrow(_stackHeight > -16, StackTooDeepException, "");
// This is a special assembly item that refers to elements pre-existing on the initial stack.
return m_stackElements[make_pair(_stackHeight, nextSequence)] =
m_expressionClasses.find(AssemblyItem(dupInstruction(1 - _stackHeight)));
} }
unsigned CommonSubexpressionEliminator::getNextStackElementSequence(int _stackHeight) ExpressionClasses::Id CommonSubexpressionEliminator::initialStackElement(int _stackHeight)
{ {
auto it = m_stackElements.upper_bound(make_pair(_stackHeight, unsigned(-1))); assertThrow(_stackHeight <= 0, OptimizerException, "Initial stack element of positive height requested.");
if (it == m_stackElements.begin()) assertThrow(_stackHeight > -16, StackTooDeepException, "");
return 0; // This is a special assembly item that refers to elements pre-existing on the initial stack.
--it; return m_expressionClasses.find(AssemblyItem(dupInstruction(1 - _stackHeight)));
if (it->first.first == _stackHeight)
return it->first.second + 1;
else
return 0;
} }
bool SemanticInformation::breaksBasicBlock(AssemblyItem const& _item) bool SemanticInformation::breaksBasicBlock(AssemblyItem const& _item)

12
libevmcore/CommonSubexpressionEliminator.h

@ -80,15 +80,15 @@ private:
void swapStackElements(int _stackHeightA, int _stackHeightB); void swapStackElements(int _stackHeightA, int _stackHeightB);
/// Retrieves the current equivalence class fo the given stack element (or generates a new /// Retrieves the current equivalence class fo the given stack element (or generates a new
/// one if it does not exist yet). /// one if it does not exist yet).
ExpressionClasses::Id getStackElement(int _stackHeight); ExpressionClasses::Id stackElement(int _stackHeight);
/// @returns the equivalence class id of the special initial stack element at the given height
/// @returns the next sequence number of the given stack element. /// (must not be positive).
unsigned getNextStackElementSequence(int _stackHeight); ExpressionClasses::Id initialStackElement(int _stackHeight);
/// Current stack height, can be negative. /// Current stack height, can be negative.
int m_stackHeight = 0; int m_stackHeight = 0;
/// Mapping (stack height, sequence number) -> equivalence class /// Current stack layout, mapping stack height -> equivalence class
std::map<std::pair<int, unsigned>, ExpressionClasses::Id> m_stackElements; std::map<int, ExpressionClasses::Id> m_stackElements;
/// Structure containing the classes of equivalent expressions. /// Structure containing the classes of equivalent expressions.
ExpressionClasses m_expressionClasses; ExpressionClasses m_expressionClasses;
}; };

Loading…
Cancel
Save