blob: 4a07357d58dc163d5b7ab1706df2406d4b593cb2 [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// 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