// 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/crankshaft/hydrogen-canonicalize.h"

#include "src/crankshaft/hydrogen-redundant-phi.h"

namespace v8 {
namespace internal {

void HCanonicalizePhase::Run() {
  const ZoneList<HBasicBlock*>* blocks(graph()->blocks());
  // Before removing no-op instructions, save their semantic value.
  // We must be careful not to set the flag unnecessarily, because GVN
  // cannot identify two instructions when their flag value differs.
  for (int i = 0; i < blocks->length(); ++i) {
    for (HInstructionIterator it(blocks->at(i)); !it.Done(); it.Advance()) {
      HInstruction* instr = it.Current();
      if (instr->IsArithmeticBinaryOperation()) {
        if (instr->representation().IsInteger32()) {
          if (instr->HasAtLeastOneUseWithFlagAndNoneWithout(
                  HInstruction::kTruncatingToInt32)) {
            instr->SetFlag(HInstruction::kAllUsesTruncatingToInt32);
          }
        } else if (instr->representation().IsSmi()) {
          if (instr->HasAtLeastOneUseWithFlagAndNoneWithout(
                  HInstruction::kTruncatingToSmi)) {
            instr->SetFlag(HInstruction::kAllUsesTruncatingToSmi);
          } else if (instr->HasAtLeastOneUseWithFlagAndNoneWithout(
                         HInstruction::kTruncatingToInt32)) {
            // Avoid redundant minus zero check
            instr->SetFlag(HInstruction::kAllUsesTruncatingToInt32);
          }
        }
      }
    }
  }

  // Perform actual Canonicalization pass.
  HRedundantPhiEliminationPhase redundant_phi_eliminator(graph());
  for (int i = 0; i < blocks->length(); ++i) {
    // Eliminate redundant phis in the block first; changes to their inputs
    // might have made them redundant, and eliminating them creates more
    // opportunities for constant folding and strength reduction.
    redundant_phi_eliminator.ProcessBlock(blocks->at(i));
    // Now canonicalize each instruction.
    for (HInstructionIterator it(blocks->at(i)); !it.Done(); it.Advance()) {
      HInstruction* instr = it.Current();
      HValue* value = instr->Canonicalize();
      if (value != instr) instr->DeleteAndReplaceWith(value);
    }
  }
}

}  // namespace internal
}  // namespace v8
