15e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org// Copyright 2014 the V8 project authors. All rights reserved.
25e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be
35e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org// found in the LICENSE file.
45e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
5ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org#include "src/compiler/common-operator.h"
6b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org#include <limits>
806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org
95e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org#include "src/compiler/operator-properties-inl.h"
109aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org#include "src/test/test-utils.h"
115e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
125e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgnamespace v8 {
135e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgnamespace internal {
145e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgnamespace compiler {
155e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
16b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
17b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org// -----------------------------------------------------------------------------
18b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org// Shared operators.
19b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
20b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
21b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.orgnamespace {
22b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
23b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.orgstruct SharedOperator {
24b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  const Operator* (CommonOperatorBuilder::*constructor)();
25b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  IrOpcode::Value opcode;
26b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  Operator::Properties properties;
27b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  int value_input_count;
28b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  int effect_input_count;
29b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  int control_input_count;
30b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  int effect_output_count;
31b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  int control_output_count;
32b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org};
33b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
34b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
35b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.orgstd::ostream& operator<<(std::ostream& os, const SharedOperator& fop) {
36b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  return os << IrOpcode::Mnemonic(fop.opcode);
37b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org}
38b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
39b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
40b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.orgconst SharedOperator kSharedOperators[] = {
41b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org#define SHARED(Name, properties, value_input_count, effect_input_count,        \
42b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org               control_input_count, effect_output_count, control_output_count) \
43b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  {                                                                            \
44b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    &CommonOperatorBuilder::Name, IrOpcode::k##Name, properties,               \
45b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org        value_input_count, effect_input_count, control_input_count,            \
46b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org        effect_output_count, control_output_count                              \
47b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  }
48b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    SHARED(Dead, Operator::kFoldable, 0, 0, 0, 0, 1),
49b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    SHARED(End, Operator::kFoldable, 0, 0, 1, 0, 0),
50b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    SHARED(Branch, Operator::kFoldable, 1, 0, 1, 0, 2),
51b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    SHARED(IfTrue, Operator::kFoldable, 0, 0, 1, 0, 1),
52b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    SHARED(IfFalse, Operator::kFoldable, 0, 0, 1, 0, 1),
53b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    SHARED(Throw, Operator::kFoldable, 1, 0, 1, 0, 1),
54b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    SHARED(Return, Operator::kNoProperties, 1, 1, 1, 1, 1),
55b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    SHARED(ControlEffect, Operator::kPure, 0, 0, 1, 1, 0)
56b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org#undef SHARED
57b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org};
58b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
59b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
60b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.orgclass CommonSharedOperatorTest
61b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    : public TestWithZone,
62b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org      public ::testing::WithParamInterface<SharedOperator> {};
63b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
64b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org}  // namespace
65b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
66b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
67b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.orgTEST_P(CommonSharedOperatorTest, InstancesAreGloballyShared) {
68b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  const SharedOperator& sop = GetParam();
69b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  CommonOperatorBuilder common1(zone());
70b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  CommonOperatorBuilder common2(zone());
71b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  EXPECT_EQ((common1.*sop.constructor)(), (common2.*sop.constructor)());
72b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org}
73b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
74b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
75b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.orgTEST_P(CommonSharedOperatorTest, NumberOfInputsAndOutputs) {
76b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  CommonOperatorBuilder common(zone());
77b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  const SharedOperator& sop = GetParam();
78b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  const Operator* op = (common.*sop.constructor)();
79b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
80b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  EXPECT_EQ(sop.value_input_count, OperatorProperties::GetValueInputCount(op));
81b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  EXPECT_EQ(sop.effect_input_count,
82b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org            OperatorProperties::GetEffectInputCount(op));
83b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  EXPECT_EQ(sop.control_input_count,
84b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org            OperatorProperties::GetControlInputCount(op));
85b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  EXPECT_EQ(
86b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org      sop.value_input_count + sop.effect_input_count + sop.control_input_count,
87b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org      OperatorProperties::GetTotalInputCount(op));
88b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
89b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  EXPECT_EQ(0, OperatorProperties::GetValueOutputCount(op));
90b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  EXPECT_EQ(sop.effect_output_count,
91b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org            OperatorProperties::GetEffectOutputCount(op));
92b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  EXPECT_EQ(sop.control_output_count,
93b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org            OperatorProperties::GetControlOutputCount(op));
94b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org}
95b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
96b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
97b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.orgTEST_P(CommonSharedOperatorTest, OpcodeIsCorrect) {
98b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  CommonOperatorBuilder common(zone());
99b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  const SharedOperator& sop = GetParam();
100b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  const Operator* op = (common.*sop.constructor)();
101b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  EXPECT_EQ(sop.opcode, op->opcode());
102b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org}
103b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
104b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
105b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.orgTEST_P(CommonSharedOperatorTest, Properties) {
106b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  CommonOperatorBuilder common(zone());
107b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  const SharedOperator& sop = GetParam();
108b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  const Operator* op = (common.*sop.constructor)();
109b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  EXPECT_EQ(sop.properties, op->properties());
110b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org}
111b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
112b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
113b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.orgINSTANTIATE_TEST_CASE_P(CommonOperatorTest, CommonSharedOperatorTest,
114b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org                        ::testing::ValuesIn(kSharedOperators));
115b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
116b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
117b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org// -----------------------------------------------------------------------------
118b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org// Other operators.
119b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
120b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
121ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgnamespace {
122ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org
1239aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.orgclass CommonOperatorTest : public TestWithZone {
124ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org public:
125ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  CommonOperatorTest() : common_(zone()) {}
126ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual ~CommonOperatorTest() {}
127ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org
128ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  CommonOperatorBuilder* common() { return &common_; }
1295e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
130ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org private:
131ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  CommonOperatorBuilder common_;
132ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org};
1335e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
1345e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
135ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgconst int kArguments[] = {1, 5, 6, 42, 100, 10000, kMaxInt};
1365e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
13706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.orgconst float kFloat32Values[] = {
13806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    std::numeric_limits<float>::min(), -1.0f, -0.0f, 0.0f, 1.0f,
13906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    std::numeric_limits<float>::max()};
14006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org
141ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org}  // namespace
1425e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
1435e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
14406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.orgTEST_F(CommonOperatorTest, Float32Constant) {
14506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  TRACED_FOREACH(float, value, kFloat32Values) {
14606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    const Operator* op = common()->Float32Constant(value);
14706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    EXPECT_FLOAT_EQ(value, OpParameter<float>(op));
14806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    EXPECT_EQ(0, OperatorProperties::GetValueInputCount(op));
14906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    EXPECT_EQ(0, OperatorProperties::GetTotalInputCount(op));
15006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    EXPECT_EQ(0, OperatorProperties::GetControlOutputCount(op));
15106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    EXPECT_EQ(0, OperatorProperties::GetEffectOutputCount(op));
15206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    EXPECT_EQ(1, OperatorProperties::GetValueOutputCount(op));
15306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  }
15406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org}
15506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org
15606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org
1575e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgTEST_F(CommonOperatorTest, ValueEffect) {
1585e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  TRACED_FOREACH(int, arguments, kArguments) {
1592c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org    const Operator* op = common()->ValueEffect(arguments);
1605e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    EXPECT_EQ(arguments, OperatorProperties::GetValueInputCount(op));
1615e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    EXPECT_EQ(arguments, OperatorProperties::GetTotalInputCount(op));
1625e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    EXPECT_EQ(0, OperatorProperties::GetControlOutputCount(op));
1635e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    EXPECT_EQ(1, OperatorProperties::GetEffectOutputCount(op));
1645e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    EXPECT_EQ(0, OperatorProperties::GetValueOutputCount(op));
1655e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  }
1665e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org}
1675e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
1685e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
1695e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgTEST_F(CommonOperatorTest, Finish) {
1705e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  TRACED_FOREACH(int, arguments, kArguments) {
1712c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org    const Operator* op = common()->Finish(arguments);
1725e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    EXPECT_EQ(1, OperatorProperties::GetValueInputCount(op));
1735e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    EXPECT_EQ(arguments, OperatorProperties::GetEffectInputCount(op));
1745e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    EXPECT_EQ(arguments + 1, OperatorProperties::GetTotalInputCount(op));
1755e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    EXPECT_EQ(0, OperatorProperties::GetControlOutputCount(op));
1765e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    EXPECT_EQ(0, OperatorProperties::GetEffectOutputCount(op));
1775e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    EXPECT_EQ(1, OperatorProperties::GetValueOutputCount(op));
1785e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  }
1795e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org}
1805e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
1815e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org}  // namespace compiler
1825e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org}  // namespace internal
1835e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org}  // namespace v8
184