deps: update v8 to 4.3.61.21
[platform/upstream/nodejs.git] / deps / v8 / test / unittests / compiler / common-operator-reducer-unittest.cc
1 // Copyright 2014 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/compiler/common-operator.h"
6 #include "src/compiler/common-operator-reducer.h"
7 #include "src/compiler/js-graph.h"
8 #include "src/compiler/js-operator.h"
9 #include "src/compiler/machine-operator.h"
10 #include "src/compiler/machine-type.h"
11 #include "src/compiler/operator.h"
12 #include "test/unittests/compiler/graph-unittest.h"
13 #include "test/unittests/compiler/node-test-utils.h"
14
15 namespace v8 {
16 namespace internal {
17 namespace compiler {
18
19 class CommonOperatorReducerTest : public GraphTest {
20  public:
21   explicit CommonOperatorReducerTest(int num_parameters = 1)
22       : GraphTest(num_parameters), machine_(zone()) {}
23   ~CommonOperatorReducerTest() OVERRIDE {}
24
25  protected:
26   Reduction Reduce(Node* node, MachineOperatorBuilder::Flags flags =
27                                    MachineOperatorBuilder::kNoFlags) {
28     JSOperatorBuilder javascript(zone());
29     MachineOperatorBuilder machine(zone(), kMachPtr, flags);
30     JSGraph jsgraph(isolate(), graph(), common(), &javascript, &machine);
31     CommonOperatorReducer reducer(&jsgraph);
32     return reducer.Reduce(node);
33   }
34
35   MachineOperatorBuilder* machine() { return &machine_; }
36
37  private:
38   MachineOperatorBuilder machine_;
39 };
40
41
42 namespace {
43
44 const BranchHint kBranchHints[] = {BranchHint::kNone, BranchHint::kFalse,
45                                    BranchHint::kTrue};
46
47
48 const MachineType kMachineTypes[] = {
49     kMachFloat32, kMachFloat64,   kMachInt8,   kMachUint8,  kMachInt16,
50     kMachUint16,  kMachInt32,     kMachUint32, kMachInt64,  kMachUint64,
51     kMachPtr,     kMachAnyTagged, kRepBit,     kRepWord8,   kRepWord16,
52     kRepWord32,   kRepWord64,     kRepFloat32, kRepFloat64, kRepTagged};
53
54
55 const Operator kOp0(0, Operator::kNoProperties, "Op0", 0, 0, 0, 1, 1, 0);
56
57 }  // namespace
58
59
60 // -----------------------------------------------------------------------------
61 // EffectPhi
62
63
64 TEST_F(CommonOperatorReducerTest, RedundantEffectPhi) {
65   const int kMaxInputs = 64;
66   Node* inputs[kMaxInputs];
67   Node* const input = graph()->NewNode(&kOp0);
68   TRACED_FORRANGE(int, input_count, 2, kMaxInputs - 1) {
69     int const value_input_count = input_count - 1;
70     for (int i = 0; i < value_input_count; ++i) {
71       inputs[i] = input;
72     }
73     inputs[value_input_count] = graph()->start();
74     Reduction r = Reduce(graph()->NewNode(
75         common()->EffectPhi(value_input_count), input_count, inputs));
76     ASSERT_TRUE(r.Changed());
77     EXPECT_EQ(input, r.replacement());
78   }
79 }
80
81
82 // -----------------------------------------------------------------------------
83 // Phi
84
85
86 TEST_F(CommonOperatorReducerTest, RedundantPhi) {
87   const int kMaxInputs = 64;
88   Node* inputs[kMaxInputs];
89   Node* const input = graph()->NewNode(&kOp0);
90   TRACED_FORRANGE(int, input_count, 2, kMaxInputs - 1) {
91     int const value_input_count = input_count - 1;
92     TRACED_FOREACH(MachineType, type, kMachineTypes) {
93       for (int i = 0; i < value_input_count; ++i) {
94         inputs[i] = graph()->start();
95       }
96       Node* merge = graph()->NewNode(common()->Merge(value_input_count),
97                                      value_input_count, inputs);
98       for (int i = 0; i < value_input_count; ++i) {
99         inputs[i] = input;
100       }
101       inputs[value_input_count] = merge;
102       Reduction r = Reduce(graph()->NewNode(
103           common()->Phi(type, value_input_count), input_count, inputs));
104       ASSERT_TRUE(r.Changed());
105       EXPECT_EQ(input, r.replacement());
106     }
107   }
108 }
109
110
111 TEST_F(CommonOperatorReducerTest, PhiToFloat64MaxOrFloat64Min) {
112   Node* p0 = Parameter(0);
113   Node* p1 = Parameter(1);
114   Node* check = graph()->NewNode(machine()->Float64LessThan(), p0, p1);
115   Node* branch = graph()->NewNode(common()->Branch(), check, graph()->start());
116   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
117   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
118   Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
119   Reduction r1 =
120       Reduce(graph()->NewNode(common()->Phi(kMachFloat64, 2), p1, p0, merge),
121              MachineOperatorBuilder::kFloat64Max);
122   ASSERT_TRUE(r1.Changed());
123   EXPECT_THAT(r1.replacement(), IsFloat64Max(p1, p0));
124   Reduction r2 =
125       Reduce(graph()->NewNode(common()->Phi(kMachFloat64, 2), p0, p1, merge),
126              MachineOperatorBuilder::kFloat64Min);
127   ASSERT_TRUE(r2.Changed());
128   EXPECT_THAT(r2.replacement(), IsFloat64Min(p0, p1));
129 }
130
131
132 // -----------------------------------------------------------------------------
133 // Select
134
135
136 TEST_F(CommonOperatorReducerTest, RedundantSelect) {
137   Node* const input = graph()->NewNode(&kOp0);
138   TRACED_FOREACH(BranchHint, hint, kBranchHints) {
139     TRACED_FOREACH(MachineType, type, kMachineTypes) {
140       Reduction r = Reduce(
141           graph()->NewNode(common()->Select(type, hint), input, input, input));
142       ASSERT_TRUE(r.Changed());
143       EXPECT_EQ(input, r.replacement());
144     }
145   }
146 }
147
148
149 TEST_F(CommonOperatorReducerTest, SelectToFloat64MaxOrFloat64Min) {
150   Node* p0 = Parameter(0);
151   Node* p1 = Parameter(1);
152   Node* check = graph()->NewNode(machine()->Float64LessThan(), p0, p1);
153   Reduction r1 =
154       Reduce(graph()->NewNode(common()->Select(kMachFloat64), check, p1, p0),
155              MachineOperatorBuilder::kFloat64Max);
156   ASSERT_TRUE(r1.Changed());
157   EXPECT_THAT(r1.replacement(), IsFloat64Max(p1, p0));
158   Reduction r2 =
159       Reduce(graph()->NewNode(common()->Select(kMachFloat64), check, p0, p1),
160              MachineOperatorBuilder::kFloat64Min);
161   ASSERT_TRUE(r2.Changed());
162   EXPECT_THAT(r2.replacement(), IsFloat64Min(p0, p1));
163 }
164
165 }  // namespace compiler
166 }  // namespace internal
167 }  // namespace v8