| Index: runtime/vm/intermediate_language.cc
|
| diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
|
| index 73c773a9498f2dd993204efec7fc1ac53030fac8..bc3ec689ff199694241bebc17a7dd2374c49a163 100644
|
| --- a/runtime/vm/intermediate_language.cc
|
| +++ b/runtime/vm/intermediate_language.cc
|
| @@ -82,10 +82,9 @@ Instruction* BranchInstr::Accept(FlowGraphVisitor* visitor) {
|
|
|
|
|
| // Default implementation of visiting basic blocks. Can be overridden.
|
| -void FlowGraphVisitor::VisitBlocks(
|
| - const GrowableArray<BlockEntryInstr*>& block_order) {
|
| - for (intptr_t i = block_order.length() - 1; i >= 0; --i) {
|
| - Instruction* current = block_order[i]->Accept(this);
|
| +void FlowGraphVisitor::VisitBlocks() {
|
| + for (intptr_t i = 0; i < block_order_.length(); ++i) {
|
| + Instruction* current = block_order_[i]->Accept(this);
|
| while ((current != NULL) && !current->IsBlockEntry()) {
|
| current = current->Accept(this);
|
| }
|
| @@ -94,78 +93,98 @@ void FlowGraphVisitor::VisitBlocks(
|
|
|
|
|
| // ==== Postorder graph traversal.
|
| -void JoinEntryInstr::Postorder(GrowableArray<BlockEntryInstr*>* block_entries) {
|
| - flip_mark();
|
| +void JoinEntryInstr::DepthFirstSearch(
|
| + GrowableArray<BlockEntryInstr*>* preorder,
|
| + GrowableArray<BlockEntryInstr*>* postorder) {
|
| + // JoinEntryInstr is the only instruction that can have more than one
|
| + // predecessor, so it is the only one that could be reached more than once
|
| + // during the traversal.
|
| + //
|
| + // Use the presence of a preorder number to indicate that it has already
|
| + // been reached.
|
| + if (preorder_number() >= 0) return;
|
| + set_preorder_number(preorder->length());
|
| + preorder->Add(this);
|
| ASSERT(successor_ != NULL);
|
| - if (successor_->mark() != mark()) successor_->Postorder(block_entries);
|
| - block_entries->Add(this);
|
| + successor_->DepthFirstSearch(preorder, postorder);
|
| + set_postorder_number(postorder->length());
|
| + postorder->Add(this);
|
| }
|
|
|
|
|
| -void TargetEntryInstr::Postorder(
|
| - GrowableArray<BlockEntryInstr*>* block_entries) {
|
| - flip_mark();
|
| +void TargetEntryInstr::DepthFirstSearch(
|
| + GrowableArray<BlockEntryInstr*>* preorder,
|
| + GrowableArray<BlockEntryInstr*>* postorder) {
|
| + ASSERT(preorder_number() == -1);
|
| + set_preorder_number(preorder->length());
|
| + preorder->Add(this);
|
| ASSERT(successor_ != NULL);
|
| - if (successor_->mark() != mark()) successor_->Postorder(block_entries);
|
| - block_entries->Add(this);
|
| + successor_->DepthFirstSearch(preorder, postorder);
|
| + set_postorder_number(postorder->length());
|
| + postorder->Add(this);
|
| }
|
|
|
|
|
| -void PickTempInstr::Postorder(GrowableArray<BlockEntryInstr*>* block_entries) {
|
| - flip_mark();
|
| +void PickTempInstr::DepthFirstSearch(
|
| + GrowableArray<BlockEntryInstr*>* preorder,
|
| + GrowableArray<BlockEntryInstr*>* postorder) {
|
| ASSERT(successor_ != NULL);
|
| - if (successor_->mark() != mark()) successor_->Postorder(block_entries);
|
| + successor_->DepthFirstSearch(preorder, postorder);
|
| }
|
|
|
|
|
| -void TuckTempInstr::Postorder(GrowableArray<BlockEntryInstr*>* block_entries) {
|
| - flip_mark();
|
| +void TuckTempInstr::DepthFirstSearch(
|
| + GrowableArray<BlockEntryInstr*>* preorder,
|
| + GrowableArray<BlockEntryInstr*>* postorder) {
|
| ASSERT(successor_ != NULL);
|
| - if (successor_->mark() != mark()) successor_->Postorder(block_entries);
|
| + successor_->DepthFirstSearch(preorder, postorder);
|
| }
|
|
|
|
|
| -void DoInstr::Postorder(GrowableArray<BlockEntryInstr*>* block_entries) {
|
| - flip_mark();
|
| +void DoInstr::DepthFirstSearch(
|
| + GrowableArray<BlockEntryInstr*>* preorder,
|
| + GrowableArray<BlockEntryInstr*>* postorder) {
|
| ASSERT(successor_ != NULL);
|
| - if (successor_->mark() != mark()) successor_->Postorder(block_entries);
|
| + successor_->DepthFirstSearch(preorder, postorder);
|
| }
|
|
|
|
|
| -void BindInstr::Postorder(GrowableArray<BlockEntryInstr*>* block_entries) {
|
| - flip_mark();
|
| +void BindInstr::DepthFirstSearch(
|
| + GrowableArray<BlockEntryInstr*>* preorder,
|
| + GrowableArray<BlockEntryInstr*>* postorder) {
|
| ASSERT(successor_ != NULL);
|
| - if (successor_->mark() != mark()) successor_->Postorder(block_entries);
|
| + successor_->DepthFirstSearch(preorder, postorder);
|
| }
|
|
|
|
|
| -void ReturnInstr::Postorder(GrowableArray<BlockEntryInstr*>* block_entries) {
|
| - flip_mark();
|
| +void ReturnInstr::DepthFirstSearch(
|
| + GrowableArray<BlockEntryInstr*>* preorder,
|
| + GrowableArray<BlockEntryInstr*>* postorder) {
|
| }
|
|
|
|
|
| -void ThrowInstr::Postorder(GrowableArray<BlockEntryInstr*>* block_entries) {
|
| - flip_mark();
|
| +void ThrowInstr::DepthFirstSearch(
|
| + GrowableArray<BlockEntryInstr*>* preorder,
|
| + GrowableArray<BlockEntryInstr*>* postorder) {
|
| }
|
|
|
|
|
| -void ReThrowInstr::Postorder(GrowableArray<BlockEntryInstr*>* block_entries) {
|
| - flip_mark();
|
| +void ReThrowInstr::DepthFirstSearch(
|
| + GrowableArray<BlockEntryInstr*>* preorder,
|
| + GrowableArray<BlockEntryInstr*>* postorder) {
|
| }
|
|
|
|
|
| -void BranchInstr::Postorder(GrowableArray<BlockEntryInstr*>* block_entries) {
|
| - flip_mark();
|
| +void BranchInstr::DepthFirstSearch(
|
| + GrowableArray<BlockEntryInstr*>* preorder,
|
| + GrowableArray<BlockEntryInstr*>* postorder) {
|
| // Visit the false successor before the true successor so they appear in
|
| - // true/false order in reverse postorder.
|
| - ASSERT(false_successor_ != NULL);
|
| + // true/false order in reverse postorder used as the block ordering in the
|
| + // nonoptimizing compiler.
|
| ASSERT(true_successor_ != NULL);
|
| - if (false_successor_->mark() != mark()) {
|
| - false_successor_->Postorder(block_entries);
|
| - }
|
| - if (true_successor_->mark() != mark()) {
|
| - true_successor_->Postorder(block_entries);
|
| - }
|
| + ASSERT(false_successor_ != NULL);
|
| + false_successor_->DepthFirstSearch(preorder, postorder);
|
| + true_successor_->DepthFirstSearch(preorder, postorder);
|
| }
|
|
|
|
|
|
|