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