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