1// Copyright 2013 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "src/crankshaft/hydrogen-canonicalize.h"
6
7#include "src/counters.h"
8#include "src/crankshaft/hydrogen-redundant-phi.h"
9#include "src/objects-inl.h"
10
11namespace v8 {
12namespace internal {
13
14void HCanonicalizePhase::Run() {
15  const ZoneList<HBasicBlock*>* blocks(graph()->blocks());
16  // Before removing no-op instructions, save their semantic value.
17  // We must be careful not to set the flag unnecessarily, because GVN
18  // cannot identify two instructions when their flag value differs.
19  for (int i = 0; i < blocks->length(); ++i) {
20    for (HInstructionIterator it(blocks->at(i)); !it.Done(); it.Advance()) {
21      HInstruction* instr = it.Current();
22      if (instr->IsArithmeticBinaryOperation()) {
23        if (instr->representation().IsInteger32()) {
24          if (instr->HasAtLeastOneUseWithFlagAndNoneWithout(
25                  HInstruction::kTruncatingToInt32)) {
26            instr->SetFlag(HInstruction::kAllUsesTruncatingToInt32);
27          }
28        } else if (instr->representation().IsSmi()) {
29          if (instr->HasAtLeastOneUseWithFlagAndNoneWithout(
30                  HInstruction::kTruncatingToSmi)) {
31            instr->SetFlag(HInstruction::kAllUsesTruncatingToSmi);
32          } else if (instr->HasAtLeastOneUseWithFlagAndNoneWithout(
33                         HInstruction::kTruncatingToInt32)) {
34            // Avoid redundant minus zero check
35            instr->SetFlag(HInstruction::kAllUsesTruncatingToInt32);
36          }
37        }
38      }
39    }
40  }
41
42  // Perform actual Canonicalization pass.
43  HRedundantPhiEliminationPhase redundant_phi_eliminator(graph());
44  for (int i = 0; i < blocks->length(); ++i) {
45    // Eliminate redundant phis in the block first; changes to their inputs
46    // might have made them redundant, and eliminating them creates more
47    // opportunities for constant folding and strength reduction.
48    redundant_phi_eliminator.ProcessBlock(blocks->at(i));
49    // Now canonicalize each instruction.
50    for (HInstructionIterator it(blocks->at(i)); !it.Done(); it.Advance()) {
51      HInstruction* instr = it.Current();
52      HValue* value = instr->Canonicalize();
53      if (value != instr) instr->DeleteAndReplaceWith(value);
54    }
55  }
56}
57
58}  // namespace internal
59}  // namespace v8
60