|
@ -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) |
|
|