// Copyright 2013 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/hydrogen-mark-unreachable.h"

namespace v8 {
namespace internal {


void HMarkUnreachableBlocksPhase::MarkUnreachableBlocks() {
  // If there is unreachable code in the graph, propagate the unreachable marks
  // using a fixed-point iteration.
  bool changed = true;
  const ZoneList<HBasicBlock*>* blocks = graph()->blocks();
  while (changed) {
    changed = false;
    for (int i = 0; i < blocks->length(); i++) {
      HBasicBlock* block = blocks->at(i);
      if (!block->IsReachable()) continue;
      bool is_reachable = blocks->at(0) == block;
      for (HPredecessorIterator it(block); !it.Done(); it.Advance()) {
        HBasicBlock* predecessor = it.Current();
        // A block is reachable if one of its predecessors is reachable,
        // doesn't deoptimize and either is known to transfer control to the
        // block or has a control flow instruction for which the next block
        // cannot be determined.
        if (predecessor->IsReachable() && !predecessor->IsDeoptimizing()) {
          HBasicBlock* pred_succ;
          bool known_pred_succ =
              predecessor->end()->KnownSuccessorBlock(&pred_succ);
          if (!known_pred_succ || pred_succ == block) {
            is_reachable = true;
            break;
          }
        }
        if (block->is_osr_entry()) {
          is_reachable = true;
        }
      }
      if (!is_reachable) {
        block->MarkUnreachable();
        changed = true;
      }
    }
  }
}


void HMarkUnreachableBlocksPhase::Run() {
  MarkUnreachableBlocks();
}

} }  // namespace v8::internal
