1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2014 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/common-operator.h"
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <limits>
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/operator-properties-inl.h"
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/test/test-utils.h"
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace compiler {
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -----------------------------------------------------------------------------
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Shared operators.
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace {
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstruct SharedOperator {
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Operator* (CommonOperatorBuilder::*constructor)();
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  IrOpcode::Value opcode;
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Operator::Properties properties;
27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int value_input_count;
28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int effect_input_count;
29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int control_input_count;
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int effect_output_count;
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int control_output_count;
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstd::ostream& operator<<(std::ostream& os, const SharedOperator& fop) {
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return os << IrOpcode::Mnemonic(fop.opcode);
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst SharedOperator kSharedOperators[] = {
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define SHARED(Name, properties, value_input_count, effect_input_count,        \
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               control_input_count, effect_output_count, control_output_count) \
43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {                                                                            \
44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    &CommonOperatorBuilder::Name, IrOpcode::k##Name, properties,               \
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        value_input_count, effect_input_count, control_input_count,            \
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        effect_output_count, control_output_count                              \
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SHARED(Dead, Operator::kFoldable, 0, 0, 0, 0, 1),
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SHARED(End, Operator::kFoldable, 0, 0, 1, 0, 0),
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SHARED(Branch, Operator::kFoldable, 1, 0, 1, 0, 2),
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SHARED(IfTrue, Operator::kFoldable, 0, 0, 1, 0, 1),
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SHARED(IfFalse, Operator::kFoldable, 0, 0, 1, 0, 1),
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SHARED(Throw, Operator::kFoldable, 1, 0, 1, 0, 1),
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SHARED(Return, Operator::kNoProperties, 1, 1, 1, 1, 1),
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SHARED(ControlEffect, Operator::kPure, 0, 0, 1, 1, 0)
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef SHARED
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass CommonSharedOperatorTest
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    : public TestWithZone,
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      public ::testing::WithParamInterface<SharedOperator> {};
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace
65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_P(CommonSharedOperatorTest, InstancesAreGloballyShared) {
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const SharedOperator& sop = GetParam();
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CommonOperatorBuilder common1(zone());
70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CommonOperatorBuilder common2(zone());
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ((common1.*sop.constructor)(), (common2.*sop.constructor)());
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_P(CommonSharedOperatorTest, NumberOfInputsAndOutputs) {
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CommonOperatorBuilder common(zone());
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const SharedOperator& sop = GetParam();
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Operator* op = (common.*sop.constructor)();
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(sop.value_input_count, OperatorProperties::GetValueInputCount(op));
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(sop.effect_input_count,
82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            OperatorProperties::GetEffectInputCount(op));
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(sop.control_input_count,
84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            OperatorProperties::GetControlInputCount(op));
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(
86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      sop.value_input_count + sop.effect_input_count + sop.control_input_count,
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      OperatorProperties::GetTotalInputCount(op));
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(0, OperatorProperties::GetValueOutputCount(op));
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(sop.effect_output_count,
91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            OperatorProperties::GetEffectOutputCount(op));
92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(sop.control_output_count,
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            OperatorProperties::GetControlOutputCount(op));
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_P(CommonSharedOperatorTest, OpcodeIsCorrect) {
98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CommonOperatorBuilder common(zone());
99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const SharedOperator& sop = GetParam();
100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Operator* op = (common.*sop.constructor)();
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(sop.opcode, op->opcode());
102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_P(CommonSharedOperatorTest, Properties) {
106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CommonOperatorBuilder common(zone());
107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const SharedOperator& sop = GetParam();
108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Operator* op = (common.*sop.constructor)();
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXPECT_EQ(sop.properties, op->properties());
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochINSTANTIATE_TEST_CASE_P(CommonOperatorTest, CommonSharedOperatorTest,
114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        ::testing::ValuesIn(kSharedOperators));
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -----------------------------------------------------------------------------
118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Other operators.
119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace {
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass CommonOperatorTest : public TestWithZone {
124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CommonOperatorTest() : common_(zone()) {}
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual ~CommonOperatorTest() {}
127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CommonOperatorBuilder* common() { return &common_; }
129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CommonOperatorBuilder common_;
132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst int kArguments[] = {1, 5, 6, 42, 100, 10000, kMaxInt};
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst float kFloat32Values[] = {
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    std::numeric_limits<float>::min(), -1.0f, -0.0f, 0.0f, 1.0f,
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    std::numeric_limits<float>::max()};
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace
142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_F(CommonOperatorTest, Float32Constant) {
145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TRACED_FOREACH(float, value, kFloat32Values) {
146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const Operator* op = common()->Float32Constant(value);
147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_FLOAT_EQ(value, OpParameter<float>(op));
148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(0, OperatorProperties::GetValueInputCount(op));
149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(0, OperatorProperties::GetTotalInputCount(op));
150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(0, OperatorProperties::GetControlOutputCount(op));
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(0, OperatorProperties::GetEffectOutputCount(op));
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(1, OperatorProperties::GetValueOutputCount(op));
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_F(CommonOperatorTest, ValueEffect) {
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TRACED_FOREACH(int, arguments, kArguments) {
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const Operator* op = common()->ValueEffect(arguments);
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(arguments, OperatorProperties::GetValueInputCount(op));
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(arguments, OperatorProperties::GetTotalInputCount(op));
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(0, OperatorProperties::GetControlOutputCount(op));
163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(1, OperatorProperties::GetEffectOutputCount(op));
164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(0, OperatorProperties::GetValueOutputCount(op));
165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST_F(CommonOperatorTest, Finish) {
170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TRACED_FOREACH(int, arguments, kArguments) {
171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const Operator* op = common()->Finish(arguments);
172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(1, OperatorProperties::GetValueInputCount(op));
173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(arguments, OperatorProperties::GetEffectInputCount(op));
174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(arguments + 1, OperatorProperties::GetTotalInputCount(op));
175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(0, OperatorProperties::GetControlOutputCount(op));
176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(0, OperatorProperties::GetEffectOutputCount(op));
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXPECT_EQ(1, OperatorProperties::GetValueOutputCount(op));
178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace compiler
182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace internal
183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace v8
184