// 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-infer-types.h"

namespace v8 {
namespace internal {

void HInferTypesPhase::InferTypes(int from_inclusive, int to_inclusive) {
  for (int i = from_inclusive; i <= to_inclusive; ++i) {
    HBasicBlock* block = graph()->blocks()->at(i);

    const ZoneList<HPhi*>* phis = block->phis();
    for (int j = 0; j < phis->length(); j++) {
      phis->at(j)->UpdateInferredType();
    }

    for (HInstructionIterator it(block); !it.Done(); it.Advance()) {
      it.Current()->UpdateInferredType();
    }

    if (block->IsLoopHeader()) {
      HBasicBlock* last_back_edge =
          block->loop_information()->GetLastBackEdge();
      InferTypes(i + 1, last_back_edge->block_id());
      // Skip all blocks already processed by the recursive call.
      i = last_back_edge->block_id();
      // Update phis of the loop header now after the whole loop body is
      // guaranteed to be processed.
      for (int j = 0; j < block->phis()->length(); ++j) {
        HPhi* phi = block->phis()->at(j);
        worklist_.Add(phi, zone());
        in_worklist_.Add(phi->id());
      }
      while (!worklist_.is_empty()) {
        HValue* current = worklist_.RemoveLast();
        in_worklist_.Remove(current->id());
        if (current->UpdateInferredType()) {
          for (HUseIterator it(current->uses()); !it.Done(); it.Advance()) {
            HValue* use = it.value();
            if (!in_worklist_.Contains(use->id())) {
              in_worklist_.Add(use->id());
              worklist_.Add(use, zone());
            }
          }
        }
      }
      ASSERT(in_worklist_.IsEmpty());
    }
  }
}

} }  // namespace v8::internal
