diff --git a/CommonSubexpressionEliminator.cpp b/CommonSubexpressionEliminator.cpp index 645a426d9..4b85eba40 100644 --- a/CommonSubexpressionEliminator.cpp +++ b/CommonSubexpressionEliminator.cpp @@ -40,9 +40,8 @@ vector 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 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 const& _initialStack, map 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 2ed926401..6e1ba40b3 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 const& _initialStack, std::map 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 m_neededBy; /// Current content of the stack. diff --git a/ExpressionClasses.cpp b/ExpressionClasses.cpp index 8d0785d37..e62f75264 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 5d32c0f71..c83520300 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 e83810d43..02c6ee136 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)