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 #ifndef V8_COMPILER_INSTRUCTION_SELECTOR_UNITTEST_H_ 6 #define V8_COMPILER_INSTRUCTION_SELECTOR_UNITTEST_H_ 7 8 #include <deque> 9 #include <set> 10 11 #include "src/base/utils/random-number-generator.h" 12 #include "src/compiler/instruction-selector.h" 13 #include "src/compiler/raw-machine-assembler.h" 14 #include "src/test/test-utils.h" 15 16 namespace v8 { 17 namespace internal { 18 namespace compiler { 19 20 class InstructionSelectorTest : public TestWithContext, public TestWithZone { 21 public: 22 InstructionSelectorTest(); 23 virtual ~InstructionSelectorTest(); 24 rng()25 base::RandomNumberGenerator* rng() { return &rng_; } 26 27 class Stream; 28 29 enum StreamBuilderMode { 30 kAllInstructions, 31 kTargetInstructions, 32 kAllExceptNopInstructions 33 }; 34 35 class StreamBuilder FINAL : public RawMachineAssembler { 36 public: StreamBuilder(InstructionSelectorTest * test,MachineType return_type)37 StreamBuilder(InstructionSelectorTest* test, MachineType return_type) 38 : RawMachineAssembler(new (test->zone()) Graph(test->zone()), 39 MakeMachineSignature(test->zone(), return_type)), 40 test_(test) {} StreamBuilder(InstructionSelectorTest * test,MachineType return_type,MachineType parameter0_type)41 StreamBuilder(InstructionSelectorTest* test, MachineType return_type, 42 MachineType parameter0_type) 43 : RawMachineAssembler( 44 new (test->zone()) Graph(test->zone()), 45 MakeMachineSignature(test->zone(), return_type, parameter0_type)), 46 test_(test) {} StreamBuilder(InstructionSelectorTest * test,MachineType return_type,MachineType parameter0_type,MachineType parameter1_type)47 StreamBuilder(InstructionSelectorTest* test, MachineType return_type, 48 MachineType parameter0_type, MachineType parameter1_type) 49 : RawMachineAssembler( 50 new (test->zone()) Graph(test->zone()), 51 MakeMachineSignature(test->zone(), return_type, parameter0_type, 52 parameter1_type)), 53 test_(test) {} StreamBuilder(InstructionSelectorTest * test,MachineType return_type,MachineType parameter0_type,MachineType parameter1_type,MachineType parameter2_type)54 StreamBuilder(InstructionSelectorTest* test, MachineType return_type, 55 MachineType parameter0_type, MachineType parameter1_type, 56 MachineType parameter2_type) 57 : RawMachineAssembler( 58 new (test->zone()) Graph(test->zone()), 59 MakeMachineSignature(test->zone(), return_type, parameter0_type, 60 parameter1_type, parameter2_type)), 61 test_(test) {} 62 Build(CpuFeature feature)63 Stream Build(CpuFeature feature) { 64 return Build(InstructionSelector::Features(feature)); 65 } Build(CpuFeature feature1,CpuFeature feature2)66 Stream Build(CpuFeature feature1, CpuFeature feature2) { 67 return Build(InstructionSelector::Features(feature1, feature2)); 68 } 69 Stream Build(StreamBuilderMode mode = kTargetInstructions) { 70 return Build(InstructionSelector::Features(), mode); 71 } 72 Stream Build(InstructionSelector::Features features, 73 StreamBuilderMode mode = kTargetInstructions); 74 75 private: MakeMachineSignature(Zone * zone,MachineType return_type)76 MachineSignature* MakeMachineSignature(Zone* zone, 77 MachineType return_type) { 78 MachineSignature::Builder builder(zone, 1, 0); 79 builder.AddReturn(return_type); 80 return builder.Build(); 81 } 82 MakeMachineSignature(Zone * zone,MachineType return_type,MachineType parameter0_type)83 MachineSignature* MakeMachineSignature(Zone* zone, MachineType return_type, 84 MachineType parameter0_type) { 85 MachineSignature::Builder builder(zone, 1, 1); 86 builder.AddReturn(return_type); 87 builder.AddParam(parameter0_type); 88 return builder.Build(); 89 } 90 MakeMachineSignature(Zone * zone,MachineType return_type,MachineType parameter0_type,MachineType parameter1_type)91 MachineSignature* MakeMachineSignature(Zone* zone, MachineType return_type, 92 MachineType parameter0_type, 93 MachineType parameter1_type) { 94 MachineSignature::Builder builder(zone, 1, 2); 95 builder.AddReturn(return_type); 96 builder.AddParam(parameter0_type); 97 builder.AddParam(parameter1_type); 98 return builder.Build(); 99 } 100 MakeMachineSignature(Zone * zone,MachineType return_type,MachineType parameter0_type,MachineType parameter1_type,MachineType parameter2_type)101 MachineSignature* MakeMachineSignature(Zone* zone, MachineType return_type, 102 MachineType parameter0_type, 103 MachineType parameter1_type, 104 MachineType parameter2_type) { 105 MachineSignature::Builder builder(zone, 1, 3); 106 builder.AddReturn(return_type); 107 builder.AddParam(parameter0_type); 108 builder.AddParam(parameter1_type); 109 builder.AddParam(parameter2_type); 110 return builder.Build(); 111 } 112 113 private: 114 InstructionSelectorTest* test_; 115 }; 116 117 class Stream FINAL { 118 public: size()119 size_t size() const { return instructions_.size(); } 120 const Instruction* operator[](size_t index) const { 121 EXPECT_LT(index, size()); 122 return instructions_[index]; 123 } 124 IsDouble(const InstructionOperand * operand)125 bool IsDouble(const InstructionOperand* operand) const { 126 return IsDouble(ToVreg(operand)); 127 } IsDouble(int virtual_register)128 bool IsDouble(int virtual_register) const { 129 return doubles_.find(virtual_register) != doubles_.end(); 130 } 131 IsInteger(const InstructionOperand * operand)132 bool IsInteger(const InstructionOperand* operand) const { 133 return IsInteger(ToVreg(operand)); 134 } IsInteger(int virtual_register)135 bool IsInteger(int virtual_register) const { 136 return !IsDouble(virtual_register) && !IsReference(virtual_register); 137 } 138 IsReference(const InstructionOperand * operand)139 bool IsReference(const InstructionOperand* operand) const { 140 return IsReference(ToVreg(operand)); 141 } IsReference(int virtual_register)142 bool IsReference(int virtual_register) const { 143 return references_.find(virtual_register) != references_.end(); 144 } 145 ToInt32(const InstructionOperand * operand)146 int32_t ToInt32(const InstructionOperand* operand) const { 147 return ToConstant(operand).ToInt32(); 148 } 149 ToInt64(const InstructionOperand * operand)150 int64_t ToInt64(const InstructionOperand* operand) const { 151 return ToConstant(operand).ToInt64(); 152 } 153 ToVreg(const InstructionOperand * operand)154 int ToVreg(const InstructionOperand* operand) const { 155 if (operand->IsConstant()) return operand->index(); 156 EXPECT_EQ(InstructionOperand::UNALLOCATED, operand->kind()); 157 return UnallocatedOperand::cast(operand)->virtual_register(); 158 } 159 GetFrameStateDescriptor(int deoptimization_id)160 FrameStateDescriptor* GetFrameStateDescriptor(int deoptimization_id) { 161 EXPECT_LT(deoptimization_id, GetFrameStateDescriptorCount()); 162 return deoptimization_entries_[deoptimization_id]; 163 } 164 GetFrameStateDescriptorCount()165 int GetFrameStateDescriptorCount() { 166 return static_cast<int>(deoptimization_entries_.size()); 167 } 168 169 private: ToConstant(const InstructionOperand * operand)170 Constant ToConstant(const InstructionOperand* operand) const { 171 ConstantMap::const_iterator i; 172 if (operand->IsConstant()) { 173 i = constants_.find(operand->index()); 174 EXPECT_FALSE(constants_.end() == i); 175 } else { 176 EXPECT_EQ(InstructionOperand::IMMEDIATE, operand->kind()); 177 i = immediates_.find(operand->index()); 178 EXPECT_FALSE(immediates_.end() == i); 179 } 180 EXPECT_EQ(operand->index(), i->first); 181 return i->second; 182 } 183 184 friend class StreamBuilder; 185 186 typedef std::map<int, Constant> ConstantMap; 187 188 ConstantMap constants_; 189 ConstantMap immediates_; 190 std::deque<Instruction*> instructions_; 191 std::set<int> doubles_; 192 std::set<int> references_; 193 std::deque<FrameStateDescriptor*> deoptimization_entries_; 194 }; 195 196 base::RandomNumberGenerator rng_; 197 }; 198 199 200 template <typename T> 201 class InstructionSelectorTestWithParam 202 : public InstructionSelectorTest, 203 public ::testing::WithParamInterface<T> {}; 204 205 } // namespace compiler 206 } // namespace internal 207 } // namespace v8 208 209 #endif // V8_COMPILER_INSTRUCTION_SELECTOR_UNITTEST_H_ 210