diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/Outlining.cpp | 12 | ||||
-rw-r--r-- | src/passes/stringify-walker-impl.h | 7 | ||||
-rw-r--r-- | src/passes/stringify-walker.h | 14 |
3 files changed, 23 insertions, 10 deletions
diff --git a/src/passes/Outlining.cpp b/src/passes/Outlining.cpp index f799d2c7a..51d000745 100644 --- a/src/passes/Outlining.cpp +++ b/src/passes/Outlining.cpp @@ -100,8 +100,20 @@ struct ReconstructStringifyWalker existingBuilder.push(curr->iff->condition); ASSERT_OK(existingBuilder.visitIfStart(curr->iff)); DBG(desc = "If Start for "); + } else if (reason.getElseStart()) { + ASSERT_OK(existingBuilder.visitElse()); + DBG(desc = "Else Start at "); } else if (reason.getEnd()) { ASSERT_OK(existingBuilder.visitEnd()); + // Outlining performs an unnested walk of the Wasm module, visiting + // each scope one at a time. IRBuilder, in contrast, expects to + // visit several nested scopes at a time. Thus, calling end() finalizes + // the control flow and places it on IRBuilder's internal stack, ready for + // the enclosing scope to consume its expressions off the stack. Since + // outlining walks unnested, the enclosing scope never arrives to retrieve + // its expressions off the stack, so we must call build() after visitEnd() + // to clear the internal stack IRBuilder manages. + ASSERT_OK(existingBuilder.build()); DBG(desc = "End for "); } else { DBG(desc = "addUniqueSymbol for unimplemented control flow "); diff --git a/src/passes/stringify-walker-impl.h b/src/passes/stringify-walker-impl.h index 8ed166d75..cca2a3405 100644 --- a/src/passes/stringify-walker-impl.h +++ b/src/passes/stringify-walker-impl.h @@ -43,7 +43,7 @@ template<typename SubType> inline void StringifyWalker<SubType>::scan(SubType* self, Expression** currp) { Expression* curr = *currp; if (Properties::isControlFlowStructure(curr)) { - self->controlFlowQueue.push(currp); + self->controlFlowQueue.push(curr); self->pushTask(doVisitExpression, currp); // The if-condition is a value child consumed by the if control flow, which // makes the if-condition a true sibling rather than part of its contents in @@ -60,9 +60,8 @@ inline void StringifyWalker<SubType>::scan(SubType* self, Expression** currp) { // of control flow. template<typename SubType> void StringifyWalker<SubType>::dequeueControlFlow() { auto& queue = controlFlowQueue; - Expression** currp = queue.front(); + Expression* curr = queue.front(); queue.pop(); - Expression* curr = *currp; // TODO: Issue #5796, Make a ControlChildIterator switch (curr->_id) { @@ -80,7 +79,7 @@ template<typename SubType> void StringifyWalker<SubType>::dequeueControlFlow() { addUniqueSymbol(SeparatorReason::makeIfStart(iff)); Super::walk(iff->ifTrue); if (iff->ifFalse) { - addUniqueSymbol(SeparatorReason::makeElseStart(iff)); + addUniqueSymbol(SeparatorReason::makeElseStart()); Super::walk(iff->ifFalse); } addUniqueSymbol(SeparatorReason::makeEnd()); diff --git a/src/passes/stringify-walker.h b/src/passes/stringify-walker.h index eb4a4482b..6f50f58d4 100644 --- a/src/passes/stringify-walker.h +++ b/src/passes/stringify-walker.h @@ -82,9 +82,7 @@ struct StringifyWalker If* iff; }; - struct ElseStart { - If* iff; - }; + struct ElseStart {}; struct LoopStart { Loop* loop; @@ -119,8 +117,8 @@ struct StringifyWalker static SeparatorReason makeIfStart(If* iff) { return SeparatorReason(IfStart{iff}); } - static SeparatorReason makeElseStart(If* iff) { - return SeparatorReason(ElseStart{iff}); + static SeparatorReason makeElseStart() { + return SeparatorReason(ElseStart{}); } static SeparatorReason makeLoopStart(Loop* loop) { return SeparatorReason(LoopStart{loop}); @@ -170,7 +168,11 @@ struct StringifyWalker return o << "~~~Undefined in operator<< overload~~~"; } - std::queue<Expression**> controlFlowQueue; + // To ensure control flow children are walked consistently during outlining, + // we push a copy of the control flow expression. This avoids an issue where + // control flow no longer points to the same expression after being + // outlined into a new function. + std::queue<Expression*> controlFlowQueue; /* * To initiate the walk, subclasses should call walkModule with a pointer to |