blob: e65d68bcca885b2a8fc0145f2c07897d189ffa34 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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
Emily Bernier958fae72015-03-24 16:35:39 -04005#ifndef V8_UNITTESTS_COMPILER_INSTRUCTION_SELECTOR_UNITTEST_H_
6#define V8_UNITTESTS_COMPILER_INSTRUCTION_SELECTOR_UNITTEST_H_
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007
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"
Emily Bernier958fae72015-03-24 16:35:39 -040014#include "src/macro-assembler.h"
15#include "test/unittests/test-utils.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000016
17namespace v8 {
18namespace internal {
19namespace compiler {
20
21class InstructionSelectorTest : public TestWithContext, public TestWithZone {
22 public:
23 InstructionSelectorTest();
Emily Bernier958fae72015-03-24 16:35:39 -040024 ~InstructionSelectorTest() OVERRIDE;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000025
26 base::RandomNumberGenerator* rng() { return &rng_; }
27
28 class Stream;
29
30 enum StreamBuilderMode {
31 kAllInstructions,
32 kTargetInstructions,
33 kAllExceptNopInstructions
34 };
35
36 class StreamBuilder FINAL : public RawMachineAssembler {
37 public:
38 StreamBuilder(InstructionSelectorTest* test, MachineType return_type)
39 : RawMachineAssembler(new (test->zone()) Graph(test->zone()),
40 MakeMachineSignature(test->zone(), return_type)),
41 test_(test) {}
42 StreamBuilder(InstructionSelectorTest* test, MachineType return_type,
43 MachineType parameter0_type)
44 : RawMachineAssembler(
45 new (test->zone()) Graph(test->zone()),
46 MakeMachineSignature(test->zone(), return_type, parameter0_type)),
47 test_(test) {}
48 StreamBuilder(InstructionSelectorTest* test, MachineType return_type,
49 MachineType parameter0_type, MachineType parameter1_type)
50 : RawMachineAssembler(
51 new (test->zone()) Graph(test->zone()),
52 MakeMachineSignature(test->zone(), return_type, parameter0_type,
53 parameter1_type)),
54 test_(test) {}
55 StreamBuilder(InstructionSelectorTest* test, MachineType return_type,
56 MachineType parameter0_type, MachineType parameter1_type,
57 MachineType parameter2_type)
58 : RawMachineAssembler(
59 new (test->zone()) Graph(test->zone()),
60 MakeMachineSignature(test->zone(), return_type, parameter0_type,
61 parameter1_type, parameter2_type)),
62 test_(test) {}
63
64 Stream Build(CpuFeature feature) {
65 return Build(InstructionSelector::Features(feature));
66 }
67 Stream Build(CpuFeature feature1, CpuFeature feature2) {
68 return Build(InstructionSelector::Features(feature1, feature2));
69 }
70 Stream Build(StreamBuilderMode mode = kTargetInstructions) {
71 return Build(InstructionSelector::Features(), mode);
72 }
73 Stream Build(InstructionSelector::Features features,
74 StreamBuilderMode mode = kTargetInstructions);
75
76 private:
77 MachineSignature* MakeMachineSignature(Zone* zone,
78 MachineType return_type) {
79 MachineSignature::Builder builder(zone, 1, 0);
80 builder.AddReturn(return_type);
81 return builder.Build();
82 }
83
84 MachineSignature* MakeMachineSignature(Zone* zone, MachineType return_type,
85 MachineType parameter0_type) {
86 MachineSignature::Builder builder(zone, 1, 1);
87 builder.AddReturn(return_type);
88 builder.AddParam(parameter0_type);
89 return builder.Build();
90 }
91
92 MachineSignature* MakeMachineSignature(Zone* zone, MachineType return_type,
93 MachineType parameter0_type,
94 MachineType parameter1_type) {
95 MachineSignature::Builder builder(zone, 1, 2);
96 builder.AddReturn(return_type);
97 builder.AddParam(parameter0_type);
98 builder.AddParam(parameter1_type);
99 return builder.Build();
100 }
101
102 MachineSignature* MakeMachineSignature(Zone* zone, MachineType return_type,
103 MachineType parameter0_type,
104 MachineType parameter1_type,
105 MachineType parameter2_type) {
106 MachineSignature::Builder builder(zone, 1, 3);
107 builder.AddReturn(return_type);
108 builder.AddParam(parameter0_type);
109 builder.AddParam(parameter1_type);
110 builder.AddParam(parameter2_type);
111 return builder.Build();
112 }
113
114 private:
115 InstructionSelectorTest* test_;
116 };
117
118 class Stream FINAL {
119 public:
120 size_t size() const { return instructions_.size(); }
121 const Instruction* operator[](size_t index) const {
122 EXPECT_LT(index, size());
123 return instructions_[index];
124 }
125
126 bool IsDouble(const InstructionOperand* operand) const {
127 return IsDouble(ToVreg(operand));
128 }
Emily Bernier958fae72015-03-24 16:35:39 -0400129
130 bool IsDouble(const Node* node) const { return IsDouble(ToVreg(node)); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000131
132 bool IsInteger(const InstructionOperand* operand) const {
133 return IsInteger(ToVreg(operand));
134 }
Emily Bernier958fae72015-03-24 16:35:39 -0400135
136 bool IsInteger(const Node* node) const { return IsInteger(ToVreg(node)); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000137
138 bool IsReference(const InstructionOperand* operand) const {
139 return IsReference(ToVreg(operand));
140 }
Emily Bernier958fae72015-03-24 16:35:39 -0400141
142 bool IsReference(const Node* node) const {
143 return IsReference(ToVreg(node));
144 }
145
146 float ToFloat32(const InstructionOperand* operand) const {
147 return ToConstant(operand).ToFloat32();
148 }
149
150 double ToFloat64(const InstructionOperand* operand) const {
151 return ToConstant(operand).ToFloat64();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000152 }
153
154 int32_t ToInt32(const InstructionOperand* operand) const {
155 return ToConstant(operand).ToInt32();
156 }
157
158 int64_t ToInt64(const InstructionOperand* operand) const {
159 return ToConstant(operand).ToInt64();
160 }
161
Emily Bernier958fae72015-03-24 16:35:39 -0400162 Handle<HeapObject> ToHeapObject(const InstructionOperand* operand) const {
163 return ToConstant(operand).ToHeapObject();
164 }
165
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000166 int ToVreg(const InstructionOperand* operand) const {
167 if (operand->IsConstant()) return operand->index();
168 EXPECT_EQ(InstructionOperand::UNALLOCATED, operand->kind());
169 return UnallocatedOperand::cast(operand)->virtual_register();
170 }
171
Emily Bernier958fae72015-03-24 16:35:39 -0400172 int ToVreg(const Node* node) const;
173
174 bool IsFixed(const InstructionOperand* operand, Register reg) const;
175 bool IsSameAsFirst(const InstructionOperand* operand) const;
176 bool IsUsedAtStart(const InstructionOperand* operand) const;
177
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000178 FrameStateDescriptor* GetFrameStateDescriptor(int deoptimization_id) {
179 EXPECT_LT(deoptimization_id, GetFrameStateDescriptorCount());
180 return deoptimization_entries_[deoptimization_id];
181 }
182
183 int GetFrameStateDescriptorCount() {
184 return static_cast<int>(deoptimization_entries_.size());
185 }
186
187 private:
Emily Bernier958fae72015-03-24 16:35:39 -0400188 bool IsDouble(int virtual_register) const {
189 return doubles_.find(virtual_register) != doubles_.end();
190 }
191
192 bool IsInteger(int virtual_register) const {
193 return !IsDouble(virtual_register) && !IsReference(virtual_register);
194 }
195
196 bool IsReference(int virtual_register) const {
197 return references_.find(virtual_register) != references_.end();
198 }
199
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000200 Constant ToConstant(const InstructionOperand* operand) const {
201 ConstantMap::const_iterator i;
202 if (operand->IsConstant()) {
203 i = constants_.find(operand->index());
204 EXPECT_FALSE(constants_.end() == i);
205 } else {
206 EXPECT_EQ(InstructionOperand::IMMEDIATE, operand->kind());
207 i = immediates_.find(operand->index());
208 EXPECT_FALSE(immediates_.end() == i);
209 }
210 EXPECT_EQ(operand->index(), i->first);
211 return i->second;
212 }
213
214 friend class StreamBuilder;
215
216 typedef std::map<int, Constant> ConstantMap;
Emily Bernier958fae72015-03-24 16:35:39 -0400217 typedef std::map<NodeId, int> VirtualRegisters;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000218
219 ConstantMap constants_;
220 ConstantMap immediates_;
221 std::deque<Instruction*> instructions_;
222 std::set<int> doubles_;
223 std::set<int> references_;
Emily Bernier958fae72015-03-24 16:35:39 -0400224 VirtualRegisters virtual_registers_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000225 std::deque<FrameStateDescriptor*> deoptimization_entries_;
226 };
227
228 base::RandomNumberGenerator rng_;
229};
230
231
232template <typename T>
233class InstructionSelectorTestWithParam
234 : public InstructionSelectorTest,
235 public ::testing::WithParamInterface<T> {};
236
237} // namespace compiler
238} // namespace internal
239} // namespace v8
240
Emily Bernier958fae72015-03-24 16:35:39 -0400241#endif // V8_UNITTESTS_COMPILER_INSTRUCTION_SELECTOR_UNITTEST_H_