aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2015-04-30 20:41:55 +0800
committerchriseth <c@ethdev.com>2015-05-06 17:10:42 +0800
commit867101e40981db56d8b72fd363e4f9e376991284 (patch)
treeba4dc55d57bf0c90960fb0755e273ca86a42c0b1
parent3ebb7d99c4e24d7bc963c419790c9f0081cc47a1 (diff)
downloaddexon-solidity-867101e40981db56d8b72fd363e4f9e376991284.tar.gz
dexon-solidity-867101e40981db56d8b72fd363e4f9e376991284.tar.zst
dexon-solidity-867101e40981db56d8b72fd363e4f9e376991284.zip
Common subexpression elimination ready for using pre-known state.
-rw-r--r--CommonSubexpressionEliminator.cpp8
-rw-r--r--CommonSubexpressionEliminator.h6
-rw-r--r--ExpressionClasses.cpp9
-rw-r--r--ExpressionClasses.h4
-rw-r--r--KnownState.cpp10
5 files changed, 14 insertions, 23 deletions
diff --git a/CommonSubexpressionEliminator.cpp b/CommonSubexpressionEliminator.cpp
index 645a426d..4b85eba4 100644
--- a/CommonSubexpressionEliminator.cpp
+++ b/CommonSubexpressionEliminator.cpp
@@ -40,9 +40,8 @@ vector<AssemblyItem> CommonSubexpressionEliminator::getOptimizedItems()
int minHeight = m_state.stackHeight() + 1;
if (!m_state.stackElements().empty())
minHeight = min(minHeight, m_state.stackElements().begin()->first);
- for (int height = minHeight; height <= 0; ++height)
- //@todo this is not nice as it is here - should be "unknownStackElement" - but is it really unknown?
- initialStackContents[height] = m_state.initialStackElement(height, SourceLocation());
+ for (int height = minHeight; height <= m_initialState.stackHeight(); ++height)
+ initialStackContents[height] = m_initialState.stackElement(height, SourceLocation());
for (int height = minHeight; height <= m_state.stackHeight(); ++height)
targetStackContents[height] = m_state.stackElement(height, SourceLocation());
@@ -50,6 +49,7 @@ vector<AssemblyItem> CommonSubexpressionEliminator::getOptimizedItems()
//stream(cout, initialStackContents, targetStackContents);
AssemblyItems items = CSECodeGenerator(m_state.expressionClasses(), m_storeOperations).generateCode(
+ m_initialState.stackHeight(),
initialStackContents,
targetStackContents
);
@@ -106,10 +106,12 @@ CSECodeGenerator::CSECodeGenerator(
}
AssemblyItems CSECodeGenerator::generateCode(
+ int _initialStackHeight,
map<int, Id> const& _initialStack,
map<int, Id> const& _targetStackContents
)
{
+ m_stackHeight = _initialStackHeight;
m_stack = _initialStack;
for (auto const& item: m_stack)
if (!m_classPositions.count(item.second))
diff --git a/CommonSubexpressionEliminator.h b/CommonSubexpressionEliminator.h
index 2ed92640..6e1ba40b 100644
--- a/CommonSubexpressionEliminator.h
+++ b/CommonSubexpressionEliminator.h
@@ -61,7 +61,7 @@ public:
using Id = ExpressionClasses::Id;
using StoreOperation = KnownState::StoreOperation;
- CommonSubexpressionEliminator(KnownState const& _state): m_state(_state) {}
+ CommonSubexpressionEliminator(KnownState const& _state): m_initialState(_state), m_state(_state) {}
/// Feeds AssemblyItems into the eliminator and @returns the iterator pointing at the first
/// item that must be fed into a new instance of the eliminator.
@@ -85,6 +85,7 @@ private:
/// Tries to optimize the item that breaks the basic block at the end.
void optimizeBreakingItem();
+ KnownState m_initialState;
KnownState m_state;
/// Keeps information about which storage or memory slots were written to at which sequence
/// number with what instruction.
@@ -115,6 +116,7 @@ public:
/// @param _targetStackContents final contents of the stack, by stack height relative to initial
/// @note should only be called once on each object.
AssemblyItems generateCode(
+ int _initialStackHeight,
std::map<int, Id> const& _initialStack,
std::map<int, Id> const& _targetStackContents
);
@@ -150,7 +152,7 @@ private:
AssemblyItems m_generatedItems;
/// Current height of the stack relative to the start.
- int m_stackHeight = 0;
+ int m_stackHeight;
/// If (b, a) is in m_requests then b is needed to compute a.
std::multimap<Id, Id> m_neededBy;
/// Current content of the stack.
diff --git a/ExpressionClasses.cpp b/ExpressionClasses.cpp
index 8d0785d3..e62f7526 100644
--- a/ExpressionClasses.cpp
+++ b/ExpressionClasses.cpp
@@ -79,15 +79,6 @@ ExpressionClasses::Id ExpressionClasses::find(
return exp.id;
}
-ExpressionClasses::Id ExpressionClasses::newId()
-{
- // Note that we cannot insert it in m_expressions because this requires item to be set.
- Expression exp;
- exp.id = m_representatives.size();
- m_representatives.push_back(exp);
- return exp.id;
-}
-
bool ExpressionClasses::knownToBeDifferent(ExpressionClasses::Id _a, ExpressionClasses::Id _b)
{
// Try to simplify "_a - _b" and return true iff the value is a non-zero constant.
diff --git a/ExpressionClasses.h b/ExpressionClasses.h
index 5d32c0f7..c8352030 100644
--- a/ExpressionClasses.h
+++ b/ExpressionClasses.h
@@ -68,10 +68,6 @@ public:
bool _copyItem = true,
unsigned _sequenceNumber = 0
);
- /// @returns a new unique class id which does not and will never have a representative containing
- /// an AssemblyItem, i.e. its value cannot be generated, instead it has to be assumed to be
- /// already present.
- Id newId();
/// @returns the canonical representative of an expression class.
Expression const& representative(Id _id) const { return m_representatives.at(_id); }
/// @returns the number of classes.
diff --git a/KnownState.cpp b/KnownState.cpp
index e83810d4..02c6ee13 100644
--- a/KnownState.cpp
+++ b/KnownState.cpp
@@ -135,8 +135,10 @@ ExpressionClasses::Id KnownState::stackElement(int _stackHeight, SourceLocation
{
if (m_stackElements.count(_stackHeight))
return m_stackElements.at(_stackHeight);
- // Stack element not found (not assigned yet), create new equivalence class.
- return m_stackElements[_stackHeight] = m_expressionClasses->newId();
+ // Stack element not found (not assigned yet), create new unknown equivalence class.
+ //@todo check that we do not infer incorrect equivalences when the stack is cleared partially
+ //in between.
+ return m_stackElements[_stackHeight] = initialStackElement(_stackHeight, _location);
}
ExpressionClasses::Id KnownState::initialStackElement(
@@ -144,10 +146,8 @@ ExpressionClasses::Id KnownState::initialStackElement(
SourceLocation const& _location
)
{
- assertThrow(_stackHeight <= 0, OptimizerException, "Initial stack element of positive height requested.");
- assertThrow(_stackHeight > -16, StackTooDeepException, "");
// This is a special assembly item that refers to elements pre-existing on the initial stack.
- return m_expressionClasses->find(AssemblyItem(dupInstruction(1 - _stackHeight), _location));
+ return m_expressionClasses->find(AssemblyItem(UndefinedItem, u256(_stackHeight), _location));
}
void KnownState::setStackElement(int _stackHeight, Id _class)