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