Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(730)

Side by Side Diff: test/cctest/compiler/test-instruction.cc

Issue 426233002: Land the Fan (disabled) (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Review feedback, rebase and "git cl format" Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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/v8.h"
6 #include "test/cctest/cctest.h"
7
8 #include "src/compiler/code-generator.h"
9 #include "src/compiler/common-operator.h"
10 #include "src/compiler/graph.h"
11 #include "src/compiler/instruction.h"
12 #include "src/compiler/machine-operator.h"
13 #include "src/compiler/node.h"
14 #include "src/compiler/operator.h"
15 #include "src/compiler/schedule.h"
16 #include "src/compiler/scheduler.h"
17 #include "src/lithium.h"
18
19 using namespace v8::internal;
20 using namespace v8::internal::compiler;
21
22 typedef v8::internal::compiler::Instruction TestInstr;
23 typedef v8::internal::compiler::InstructionSequence TestInstrSeq;
24
25 // A testing helper for the register code abstraction.
26 class InstructionTester : public HandleAndZoneScope {
27 public: // We're all friends here.
28 explicit InstructionTester()
29 : isolate(main_isolate()),
30 graph(zone()),
31 schedule(zone()),
32 info(static_cast<HydrogenCodeStub*>(NULL), main_isolate()),
33 linkage(&info),
34 common(zone()),
35 machine(zone(), kMachineWord32),
36 code(NULL) {}
37
38 Isolate* isolate;
39 Graph graph;
40 Schedule schedule;
41 CompilationInfoWithZone info;
42 Linkage linkage;
43 CommonOperatorBuilder common;
44 MachineOperatorBuilder machine;
45 TestInstrSeq* code;
46
47 Zone* zone() { return main_zone(); }
48
49 void allocCode() {
50 if (schedule.rpo_order()->size() == 0) {
51 // Compute the RPO order.
52 Scheduler scheduler(zone(), &graph, &schedule);
53 scheduler.ComputeSpecialRPO();
54 ASSERT(schedule.rpo_order()->size() > 0);
55 }
56 code = new TestInstrSeq(&linkage, &graph, &schedule);
57 }
58
59 Node* Int32Constant(int32_t val) {
60 Node* node = graph.NewNode(common.Int32Constant(val));
61 schedule.AddNode(schedule.entry(), node);
62 return node;
63 }
64
65 Node* Float64Constant(double val) {
66 Node* node = graph.NewNode(common.Float64Constant(val));
67 schedule.AddNode(schedule.entry(), node);
68 return node;
69 }
70
71 Node* Parameter(int32_t which) {
72 Node* node = graph.NewNode(common.Parameter(which));
73 schedule.AddNode(schedule.entry(), node);
74 return node;
75 }
76
77 Node* NewNode(BasicBlock* block) {
78 Node* node = graph.NewNode(common.Int32Constant(111));
79 schedule.AddNode(block, node);
80 return node;
81 }
82
83 int NewInstr(BasicBlock* block) {
84 InstructionCode opcode = static_cast<InstructionCode>(110);
85 TestInstr* instr = TestInstr::New(zone(), opcode);
86 return code->AddInstruction(instr, block);
87 }
88
89 UnallocatedOperand* NewUnallocated(int vreg) {
90 UnallocatedOperand* unallocated =
91 new (zone()) UnallocatedOperand(UnallocatedOperand::ANY);
92 unallocated->set_virtual_register(vreg);
93 return unallocated;
94 }
95 };
96
97
98 TEST(InstructionBasic) {
99 InstructionTester R;
100
101 for (int i = 0; i < 10; i++) {
102 R.Int32Constant(i); // Add some nodes to the graph.
103 }
104
105 BasicBlock* last = R.schedule.entry();
106 for (int i = 0; i < 5; i++) {
107 BasicBlock* block = R.schedule.NewBasicBlock();
108 R.schedule.AddGoto(last, block);
109 last = block;
110 }
111
112 R.allocCode();
113
114 CHECK_EQ(R.graph.NodeCount(), R.code->ValueCount());
115
116 BasicBlockVector* blocks = R.schedule.rpo_order();
117 CHECK_EQ(static_cast<int>(blocks->size()), R.code->BasicBlockCount());
118
119 int index = 0;
120 for (BasicBlockVectorIter i = blocks->begin(); i != blocks->end();
121 i++, index++) {
122 BasicBlock* block = *i;
123 CHECK_EQ(block, R.code->BlockAt(index));
124 CHECK_EQ(-1, R.code->GetLoopEnd(block));
125 }
126 }
127
128
129 TEST(InstructionGetBasicBlock) {
130 InstructionTester R;
131
132 BasicBlock* b0 = R.schedule.entry();
133 BasicBlock* b1 = R.schedule.NewBasicBlock();
134 BasicBlock* b2 = R.schedule.NewBasicBlock();
135 BasicBlock* b3 = R.schedule.exit();
136
137 R.schedule.AddGoto(b0, b1);
138 R.schedule.AddGoto(b1, b2);
139 R.schedule.AddGoto(b2, b3);
140
141 R.allocCode();
142
143 R.code->StartBlock(b0);
144 int i0 = R.NewInstr(b0);
145 int i1 = R.NewInstr(b0);
146 R.code->EndBlock(b0);
147 R.code->StartBlock(b1);
148 int i2 = R.NewInstr(b1);
149 int i3 = R.NewInstr(b1);
150 int i4 = R.NewInstr(b1);
151 int i5 = R.NewInstr(b1);
152 R.code->EndBlock(b1);
153 R.code->StartBlock(b2);
154 int i6 = R.NewInstr(b2);
155 int i7 = R.NewInstr(b2);
156 int i8 = R.NewInstr(b2);
157 R.code->EndBlock(b2);
158 R.code->StartBlock(b3);
159 R.code->EndBlock(b3);
160
161 CHECK_EQ(b0, R.code->GetBasicBlock(i0));
162 CHECK_EQ(b0, R.code->GetBasicBlock(i1));
163
164 CHECK_EQ(b1, R.code->GetBasicBlock(i2));
165 CHECK_EQ(b1, R.code->GetBasicBlock(i3));
166 CHECK_EQ(b1, R.code->GetBasicBlock(i4));
167 CHECK_EQ(b1, R.code->GetBasicBlock(i5));
168
169 CHECK_EQ(b2, R.code->GetBasicBlock(i6));
170 CHECK_EQ(b2, R.code->GetBasicBlock(i7));
171 CHECK_EQ(b2, R.code->GetBasicBlock(i8));
172
173 CHECK_EQ(b0, R.code->GetBasicBlock(b0->first_instruction_index()));
174 CHECK_EQ(b0, R.code->GetBasicBlock(b0->last_instruction_index()));
175
176 CHECK_EQ(b1, R.code->GetBasicBlock(b1->first_instruction_index()));
177 CHECK_EQ(b1, R.code->GetBasicBlock(b1->last_instruction_index()));
178
179 CHECK_EQ(b2, R.code->GetBasicBlock(b2->first_instruction_index()));
180 CHECK_EQ(b2, R.code->GetBasicBlock(b2->last_instruction_index()));
181
182 CHECK_EQ(b3, R.code->GetBasicBlock(b3->first_instruction_index()));
183 CHECK_EQ(b3, R.code->GetBasicBlock(b3->last_instruction_index()));
184 }
185
186
187 TEST(InstructionIsGapAt) {
188 InstructionTester R;
189
190 BasicBlock* b0 = R.schedule.entry();
191 R.schedule.AddReturn(b0, R.Int32Constant(1));
192
193 R.allocCode();
194 TestInstr* i0 = TestInstr::New(R.zone(), 100);
195 TestInstr* g = TestInstr::New(R.zone(), 103)->MarkAsControl();
196 R.code->StartBlock(b0);
197 R.code->AddInstruction(i0, b0);
198 R.code->AddInstruction(g, b0);
199 R.code->EndBlock(b0);
200
201 CHECK_EQ(true, R.code->InstructionAt(0)->IsBlockStart());
202
203 CHECK_EQ(true, R.code->IsGapAt(0)); // Label
204 CHECK_EQ(true, R.code->IsGapAt(1)); // Gap
205 CHECK_EQ(false, R.code->IsGapAt(2)); // i0
206 CHECK_EQ(true, R.code->IsGapAt(3)); // Gap
207 CHECK_EQ(true, R.code->IsGapAt(4)); // Gap
208 CHECK_EQ(false, R.code->IsGapAt(5)); // g
209 }
210
211
212 TEST(InstructionIsGapAt2) {
213 InstructionTester R;
214
215 BasicBlock* b0 = R.schedule.entry();
216 BasicBlock* b1 = R.schedule.exit();
217 R.schedule.AddGoto(b0, b1);
218 R.schedule.AddReturn(b1, R.Int32Constant(1));
219
220 R.allocCode();
221 TestInstr* i0 = TestInstr::New(R.zone(), 100);
222 TestInstr* g = TestInstr::New(R.zone(), 103)->MarkAsControl();
223 R.code->StartBlock(b0);
224 R.code->AddInstruction(i0, b0);
225 R.code->AddInstruction(g, b0);
226 R.code->EndBlock(b0);
227
228 TestInstr* i1 = TestInstr::New(R.zone(), 102);
229 TestInstr* g1 = TestInstr::New(R.zone(), 104)->MarkAsControl();
230 R.code->StartBlock(b1);
231 R.code->AddInstruction(i1, b1);
232 R.code->AddInstruction(g1, b1);
233 R.code->EndBlock(b1);
234
235 CHECK_EQ(true, R.code->InstructionAt(0)->IsBlockStart());
236
237 CHECK_EQ(true, R.code->IsGapAt(0)); // Label
238 CHECK_EQ(true, R.code->IsGapAt(1)); // Gap
239 CHECK_EQ(false, R.code->IsGapAt(2)); // i0
240 CHECK_EQ(true, R.code->IsGapAt(3)); // Gap
241 CHECK_EQ(true, R.code->IsGapAt(4)); // Gap
242 CHECK_EQ(false, R.code->IsGapAt(5)); // g
243
244 CHECK_EQ(true, R.code->InstructionAt(6)->IsBlockStart());
245
246 CHECK_EQ(true, R.code->IsGapAt(6)); // Label
247 CHECK_EQ(true, R.code->IsGapAt(7)); // Gap
248 CHECK_EQ(false, R.code->IsGapAt(8)); // i1
249 CHECK_EQ(true, R.code->IsGapAt(9)); // Gap
250 CHECK_EQ(true, R.code->IsGapAt(10)); // Gap
251 CHECK_EQ(false, R.code->IsGapAt(11)); // g1
252 }
253
254
255 TEST(InstructionAddGapMove) {
256 InstructionTester R;
257
258 BasicBlock* b0 = R.schedule.entry();
259 R.schedule.AddReturn(b0, R.Int32Constant(1));
260
261 R.allocCode();
262 TestInstr* i0 = TestInstr::New(R.zone(), 100);
263 TestInstr* g = TestInstr::New(R.zone(), 103)->MarkAsControl();
264 R.code->StartBlock(b0);
265 R.code->AddInstruction(i0, b0);
266 R.code->AddInstruction(g, b0);
267 R.code->EndBlock(b0);
268
269 CHECK_EQ(true, R.code->InstructionAt(0)->IsBlockStart());
270
271 CHECK_EQ(true, R.code->IsGapAt(0)); // Label
272 CHECK_EQ(true, R.code->IsGapAt(1)); // Gap
273 CHECK_EQ(false, R.code->IsGapAt(2)); // i0
274 CHECK_EQ(true, R.code->IsGapAt(3)); // Gap
275 CHECK_EQ(true, R.code->IsGapAt(4)); // Gap
276 CHECK_EQ(false, R.code->IsGapAt(5)); // g
277
278 int indexes[] = {0, 1, 3, 4, -1};
279 for (int i = 0; indexes[i] >= 0; i++) {
280 int index = indexes[i];
281
282 UnallocatedOperand* op1 = R.NewUnallocated(index + 6);
283 UnallocatedOperand* op2 = R.NewUnallocated(index + 12);
284
285 R.code->AddGapMove(index, op1, op2);
286 GapInstruction* gap = R.code->GapAt(index);
287 ParallelMove* move = gap->GetParallelMove(GapInstruction::START);
288 CHECK_NE(NULL, move);
289 const ZoneList<MoveOperands>* move_operands = move->move_operands();
290 CHECK_EQ(1, move_operands->length());
291 MoveOperands* cur = &move_operands->at(0);
292 CHECK_EQ(op1, cur->source());
293 CHECK_EQ(op2, cur->destination());
294 }
295 }
296
297
298 TEST(InstructionOperands) {
299 Zone zone(CcTest::InitIsolateOnce());
300
301 {
302 TestInstr* i = TestInstr::New(&zone, 101);
303 CHECK_EQ(0, i->OutputCount());
304 CHECK_EQ(0, i->InputCount());
305 CHECK_EQ(0, i->TempCount());
306 }
307
308 InstructionOperand* outputs[] = {
309 new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER),
310 new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER),
311 new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER),
312 new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER)};
313
314 InstructionOperand* inputs[] = {
315 new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER),
316 new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER),
317 new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER),
318 new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER)};
319
320 InstructionOperand* temps[] = {
321 new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER),
322 new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER),
323 new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER),
324 new (&zone) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER)};
325
326 for (size_t i = 0; i < ARRAY_SIZE(outputs); i++) {
327 for (size_t j = 0; j < ARRAY_SIZE(inputs); j++) {
328 for (size_t k = 0; k < ARRAY_SIZE(temps); k++) {
329 TestInstr* m =
330 TestInstr::New(&zone, 101, i, outputs, j, inputs, k, temps);
331 CHECK(i == m->OutputCount());
332 CHECK(j == m->InputCount());
333 CHECK(k == m->TempCount());
334
335 for (size_t z = 0; z < i; z++) {
336 CHECK_EQ(outputs[z], m->OutputAt(z));
337 }
338
339 for (size_t z = 0; z < j; z++) {
340 CHECK_EQ(inputs[z], m->InputAt(z));
341 }
342
343 for (size_t z = 0; z < k; z++) {
344 CHECK_EQ(temps[z], m->TempAt(z));
345 }
346 }
347 }
348 }
349 }
OLDNEW
« no previous file with comments | « test/cctest/compiler/test-graph-reducer.cc ('k') | test/cctest/compiler/test-instruction-selector.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698