OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_UNITTESTS_COMPILER_INSTRUCTION_SEQUENCE_UNITTEST_H_ | 5 #ifndef V8_UNITTESTS_COMPILER_INSTRUCTION_SEQUENCE_UNITTEST_H_ |
6 #define V8_UNITTESTS_COMPILER_INSTRUCTION_SEQUENCE_UNITTEST_H_ | 6 #define V8_UNITTESTS_COMPILER_INSTRUCTION_SEQUENCE_UNITTEST_H_ |
7 | 7 |
8 #include <memory> | 8 #include <memory> |
9 | 9 |
10 #include "src/compiler/instruction.h" | 10 #include "src/compiler/instruction.h" |
11 #include "test/unittests/test-utils.h" | 11 #include "test/unittests/test-utils.h" |
12 #include "testing/gmock/include/gmock/gmock.h" | 12 #include "testing/gmock/include/gmock/gmock.h" |
13 | 13 |
14 namespace v8 { | 14 namespace v8 { |
15 namespace internal { | 15 namespace internal { |
16 namespace compiler { | 16 namespace compiler { |
17 | 17 |
18 class InstructionSequenceTest : public TestWithIsolateAndZone { | 18 class InstructionSequenceTest : public TestWithIsolateAndZone { |
19 public: | 19 public: |
20 static const int kDefaultNRegs = 8; | 20 static const int kDefaultNRegs = 8; |
21 static const int kNoValue = kMinInt; | 21 static const int kNoValue = kMinInt; |
| 22 static const MachineRepresentation kNoRep = MachineRepresentation::kNone; |
| 23 static const MachineRepresentation kFloat64 = MachineRepresentation::kFloat64; |
22 | 24 |
23 typedef RpoNumber Rpo; | 25 typedef RpoNumber Rpo; |
24 | 26 |
25 struct VReg { | 27 struct VReg { |
26 VReg() : value_(kNoValue) {} | 28 VReg() : value_(kNoValue) {} |
27 VReg(PhiInstruction* phi) : value_(phi->virtual_register()) {} // NOLINT | 29 VReg(PhiInstruction* phi) : value_(phi->virtual_register()) {} // NOLINT |
28 explicit VReg(int value) : value_(value) {} | 30 explicit VReg(int value, MachineRepresentation rep = kNoRep) |
| 31 : value_(value), rep_(rep) {} |
29 int value_; | 32 int value_; |
| 33 MachineRepresentation rep_ = kNoRep; |
30 }; | 34 }; |
31 | 35 |
32 typedef std::pair<VReg, VReg> VRegPair; | 36 typedef std::pair<VReg, VReg> VRegPair; |
33 | 37 |
34 enum TestOperandType { | 38 enum TestOperandType { |
35 kInvalid, | 39 kInvalid, |
36 kSameAsFirst, | 40 kSameAsFirst, |
37 kRegister, | 41 kRegister, |
38 kFixedRegister, | 42 kFixedRegister, |
39 kSlot, | 43 kSlot, |
40 kFixedSlot, | 44 kFixedSlot, |
41 kExplicit, | 45 kExplicit, |
42 kImmediate, | 46 kImmediate, |
43 kNone, | 47 kNone, |
44 kConstant, | 48 kConstant, |
45 kUnique, | 49 kUnique, |
46 kUniqueRegister | 50 kUniqueRegister |
47 }; | 51 }; |
48 | 52 |
49 struct TestOperand { | 53 struct TestOperand { |
50 TestOperand() : type_(kInvalid), vreg_(), value_(kNoValue) {} | 54 TestOperand() : type_(kInvalid), vreg_(), value_(kNoValue), rep_(kNoRep) {} |
51 TestOperand(TestOperandType type, int imm) | 55 explicit TestOperand(TestOperandType type) |
52 : type_(type), vreg_(), value_(imm) {} | 56 : type_(type), vreg_(), value_(kNoValue), rep_(kNoRep) {} |
| 57 // For tests that do register allocation. |
53 TestOperand(TestOperandType type, VReg vreg, int value = kNoValue) | 58 TestOperand(TestOperandType type, VReg vreg, int value = kNoValue) |
54 : type_(type), vreg_(vreg), value_(value) {} | 59 : type_(type), vreg_(vreg), value_(value), rep_(vreg.rep_) {} |
| 60 // For immediates, constants, and tests that don't do register allocation. |
| 61 TestOperand(TestOperandType type, int value, |
| 62 MachineRepresentation rep = kNoRep) |
| 63 : type_(type), vreg_(), value_(value), rep_(rep) {} |
55 | 64 |
56 TestOperandType type_; | 65 TestOperandType type_; |
57 VReg vreg_; | 66 VReg vreg_; |
58 int value_; | 67 int value_; |
| 68 MachineRepresentation rep_; |
59 }; | 69 }; |
60 | 70 |
61 static TestOperand Same() { return TestOperand(kSameAsFirst, VReg()); } | 71 static TestOperand Same() { return TestOperand(kSameAsFirst); } |
62 | 72 |
63 static TestOperand ExplicitReg(int index) { | 73 static TestOperand ExplicitReg(int index) { |
64 TestOperandType type = kExplicit; | 74 TestOperandType type = kExplicit; |
65 return TestOperand(type, VReg(), index); | 75 return TestOperand(type, index); |
| 76 } |
| 77 |
| 78 static TestOperand ExplicitFPReg(int index, |
| 79 MachineRepresentation rep = kFloat64) { |
| 80 TestOperandType type = kExplicit; |
| 81 return TestOperand(type, index, rep); |
66 } | 82 } |
67 | 83 |
68 static TestOperand Reg(VReg vreg, int index = kNoValue) { | 84 static TestOperand Reg(VReg vreg, int index = kNoValue) { |
69 TestOperandType type = kRegister; | 85 TestOperandType type = (index == kNoValue) ? kRegister : kFixedRegister; |
70 if (index != kNoValue) type = kFixedRegister; | |
71 return TestOperand(type, vreg, index); | 86 return TestOperand(type, vreg, index); |
72 } | 87 } |
73 | 88 |
74 static TestOperand Reg(int index = kNoValue) { return Reg(VReg(), index); } | 89 static TestOperand Reg(int index = kNoValue, |
| 90 MachineRepresentation rep = kNoRep) { |
| 91 return Reg(VReg(kNoValue, rep), index); |
| 92 } |
| 93 |
| 94 static TestOperand FPReg(int index = kNoValue, |
| 95 MachineRepresentation rep = kFloat64) { |
| 96 return Reg(index, rep); |
| 97 } |
75 | 98 |
76 static TestOperand Slot(VReg vreg, int index = kNoValue) { | 99 static TestOperand Slot(VReg vreg, int index = kNoValue) { |
77 TestOperandType type = kSlot; | 100 TestOperandType type = (index == kNoValue) ? kSlot : kFixedSlot; |
78 if (index != kNoValue) type = kFixedSlot; | |
79 return TestOperand(type, vreg, index); | 101 return TestOperand(type, vreg, index); |
80 } | 102 } |
81 | 103 |
82 static TestOperand Slot(int index = kNoValue) { return Slot(VReg(), index); } | 104 static TestOperand Slot(int index = kNoValue, |
| 105 MachineRepresentation rep = kNoRep) { |
| 106 return Slot(VReg(kNoValue, rep), index); |
| 107 } |
83 | 108 |
84 static TestOperand Const(int index) { | 109 static TestOperand Const(int index) { |
85 CHECK_NE(kNoValue, index); | 110 CHECK_NE(kNoValue, index); |
86 return TestOperand(kConstant, VReg(), index); | 111 return TestOperand(kConstant, index); |
87 } | 112 } |
88 | 113 |
89 static TestOperand Use(VReg vreg) { return TestOperand(kNone, vreg); } | 114 static TestOperand Use(VReg vreg) { return TestOperand(kNone, vreg); } |
90 | 115 |
91 static TestOperand Use() { return Use(VReg()); } | 116 static TestOperand Use() { return Use(VReg()); } |
92 | 117 |
93 static TestOperand Unique(VReg vreg) { return TestOperand(kUnique, vreg); } | 118 static TestOperand Unique(VReg vreg) { return TestOperand(kUnique, vreg); } |
94 | 119 |
95 static TestOperand UniqueReg(VReg vreg) { | 120 static TestOperand UniqueReg(VReg vreg) { |
96 return TestOperand(kUniqueRegister, vreg); | 121 return TestOperand(kUniqueRegister, vreg); |
(...skipping 25 matching lines...) Expand all Loading... |
122 } | 147 } |
123 | 148 |
124 static BlockCompletion Last() { | 149 static BlockCompletion Last() { |
125 BlockCompletion completion = {kBlockEnd, TestOperand(), kNoValue, kNoValue}; | 150 BlockCompletion completion = {kBlockEnd, TestOperand(), kNoValue, kNoValue}; |
126 return completion; | 151 return completion; |
127 } | 152 } |
128 | 153 |
129 InstructionSequenceTest(); | 154 InstructionSequenceTest(); |
130 | 155 |
131 void SetNumRegs(int num_general_registers, int num_double_registers); | 156 void SetNumRegs(int num_general_registers, int num_double_registers); |
| 157 int GetNumRegs(MachineRepresentation rep); |
| 158 int GetAllocatableCode(int index, MachineRepresentation rep = kNoRep); |
132 RegisterConfiguration* config(); | 159 RegisterConfiguration* config(); |
133 InstructionSequence* sequence(); | 160 InstructionSequence* sequence(); |
134 | 161 |
135 void StartLoop(int loop_blocks); | 162 void StartLoop(int loop_blocks); |
136 void EndLoop(); | 163 void EndLoop(); |
137 void StartBlock(bool deferred = false); | 164 void StartBlock(bool deferred = false); |
138 Instruction* EndBlock(BlockCompletion completion = FallThrough()); | 165 Instruction* EndBlock(BlockCompletion completion = FallThrough()); |
139 | 166 |
140 TestOperand Imm(int32_t imm = 0); | 167 TestOperand Imm(int32_t imm = 0); |
141 VReg Define(TestOperand output_op); | 168 VReg Define(TestOperand output_op); |
142 VReg Parameter(TestOperand output_op = Reg()) { return Define(output_op); } | 169 VReg Parameter(TestOperand output_op = Reg()) { return Define(output_op); } |
| 170 VReg FPParameter(MachineRepresentation rep = kFloat64) { |
| 171 return Parameter(FPReg(kNoValue, rep)); |
| 172 } |
| 173 |
| 174 MachineRepresentation GetCanonicalRep(TestOperand op) { |
| 175 return IsFloatingPoint(op.rep_) ? op.rep_ |
| 176 : sequence()->DefaultRepresentation(); |
| 177 } |
143 | 178 |
144 Instruction* Return(TestOperand input_op_0); | 179 Instruction* Return(TestOperand input_op_0); |
145 Instruction* Return(VReg vreg) { return Return(Reg(vreg, 0)); } | 180 Instruction* Return(VReg vreg) { return Return(Reg(vreg, 0)); } |
146 | 181 |
147 PhiInstruction* Phi(VReg incoming_vreg_0 = VReg(), | 182 PhiInstruction* Phi(VReg incoming_vreg_0 = VReg(), |
148 VReg incoming_vreg_1 = VReg(), | 183 VReg incoming_vreg_1 = VReg(), |
149 VReg incoming_vreg_2 = VReg(), | 184 VReg incoming_vreg_2 = VReg(), |
150 VReg incoming_vreg_3 = VReg()); | 185 VReg incoming_vreg_3 = VReg()); |
151 PhiInstruction* Phi(VReg incoming_vreg_0, size_t input_count); | 186 PhiInstruction* Phi(VReg incoming_vreg_0, size_t input_count); |
152 void SetInput(PhiInstruction* phi, size_t input, VReg vreg); | 187 void SetInput(PhiInstruction* phi, size_t input, VReg vreg); |
(...skipping 17 matching lines...) Expand all Loading... |
170 TestOperand input_op_1 = TestOperand(), | 205 TestOperand input_op_1 = TestOperand(), |
171 TestOperand input_op_2 = TestOperand(), | 206 TestOperand input_op_2 = TestOperand(), |
172 TestOperand input_op_3 = TestOperand()); | 207 TestOperand input_op_3 = TestOperand()); |
173 VReg EmitCall(TestOperand output_op, size_t input_size, TestOperand* inputs); | 208 VReg EmitCall(TestOperand output_op, size_t input_size, TestOperand* inputs); |
174 VReg EmitCall(TestOperand output_op, TestOperand input_op_0 = TestOperand(), | 209 VReg EmitCall(TestOperand output_op, TestOperand input_op_0 = TestOperand(), |
175 TestOperand input_op_1 = TestOperand(), | 210 TestOperand input_op_1 = TestOperand(), |
176 TestOperand input_op_2 = TestOperand(), | 211 TestOperand input_op_2 = TestOperand(), |
177 TestOperand input_op_3 = TestOperand()); | 212 TestOperand input_op_3 = TestOperand()); |
178 | 213 |
179 InstructionBlock* current_block() const { return current_block_; } | 214 InstructionBlock* current_block() const { return current_block_; } |
180 int num_general_registers() const { return num_general_registers_; } | |
181 int num_double_registers() const { return num_double_registers_; } | |
182 | 215 |
183 // Called after all instructions have been inserted. | 216 // Called after all instructions have been inserted. |
184 void WireBlocks(); | 217 void WireBlocks(); |
185 | 218 |
186 private: | 219 private: |
187 VReg NewReg() { return VReg(sequence()->NextVirtualRegister()); } | 220 virtual bool DoesRegisterAllocation() const { return true; } |
188 | 221 |
189 static TestOperand Invalid() { return TestOperand(kInvalid, VReg()); } | 222 VReg NewReg(TestOperand op = TestOperand()) { |
| 223 int vreg = sequence()->NextVirtualRegister(); |
| 224 if (IsFloatingPoint(op.rep_)) |
| 225 sequence()->MarkAsRepresentation(op.rep_, vreg); |
| 226 return VReg(vreg, op.rep_); |
| 227 } |
| 228 |
| 229 static TestOperand Invalid() { return TestOperand(kInvalid); } |
190 | 230 |
191 Instruction* EmitBranch(TestOperand input_op); | 231 Instruction* EmitBranch(TestOperand input_op); |
192 Instruction* EmitFallThrough(); | 232 Instruction* EmitFallThrough(); |
193 Instruction* EmitJump(); | 233 Instruction* EmitJump(); |
194 Instruction* NewInstruction(InstructionCode code, size_t outputs_size, | 234 Instruction* NewInstruction(InstructionCode code, size_t outputs_size, |
195 InstructionOperand* outputs, | 235 InstructionOperand* outputs, |
196 size_t inputs_size = 0, | 236 size_t inputs_size = 0, |
197 InstructionOperand* inputs = nullptr, | 237 InstructionOperand* inputs = nullptr, |
198 size_t temps_size = 0, | 238 size_t temps_size = 0, |
199 InstructionOperand* temps = nullptr); | 239 InstructionOperand* temps = nullptr); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 bool block_returns_; | 285 bool block_returns_; |
246 | 286 |
247 DISALLOW_COPY_AND_ASSIGN(InstructionSequenceTest); | 287 DISALLOW_COPY_AND_ASSIGN(InstructionSequenceTest); |
248 }; | 288 }; |
249 | 289 |
250 } // namespace compiler | 290 } // namespace compiler |
251 } // namespace internal | 291 } // namespace internal |
252 } // namespace v8 | 292 } // namespace v8 |
253 | 293 |
254 #endif // V8_UNITTESTS_COMPILER_INSTRUCTION_SEQUENCE_UNITTEST_H_ | 294 #endif // V8_UNITTESTS_COMPILER_INSTRUCTION_SEQUENCE_UNITTEST_H_ |
OLD | NEW |