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

Side by Side Diff: src/compiler/machine-graph-verifier.cc

Issue 2388313003: [turbofan] Introduces a step to verify the machine graph. (Closed)
Patch Set: Fix win build. Created 4 years, 2 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
« no previous file with comments | « src/compiler/machine-graph-verifier.h ('k') | src/compiler/machine-operator.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 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/compiler/machine-graph-verifier.h"
6
7 #include "src/compiler/common-operator.h"
8 #include "src/compiler/graph.h"
9 #include "src/compiler/linkage.h"
10 #include "src/compiler/machine-operator.h"
11 #include "src/compiler/node-properties.h"
12 #include "src/compiler/node.h"
13 #include "src/compiler/schedule.h"
14 #include "src/zone/zone.h"
15
16 namespace v8 {
17 namespace internal {
18 namespace compiler {
19
20 namespace {
21
22 class MachineRepresentationInferrer {
23 public:
24 MachineRepresentationInferrer(Schedule const* schedule, Graph const* graph,
25 Linkage* linkage, Zone* zone)
26 : schedule_(schedule),
27 linkage_(linkage),
28 representation_vector_(graph->NodeCount(), zone) {
Jarin 2016/10/05 08:16:17 Explicit initialization with MachineRepresentation
29 Run();
30 }
31
32 MachineRepresentation GetRepresentation(Node const* node) const {
33 return representation_vector_.at(node->id());
34 }
35
36 private:
37 MachineRepresentation GetProjectionType(Node const* projection) {
38 size_t index = ProjectionIndexOf(projection->op());
39 Node* input = projection->InputAt(0);
40 switch (input->opcode()) {
41 case IrOpcode::kInt32AddWithOverflow:
42 case IrOpcode::kInt32SubWithOverflow:
43 case IrOpcode::kInt32MulWithOverflow:
44 CHECK_LE(index, static_cast<size_t>(1));
45 return index == 0 ? MachineRepresentation::kWord32
46 : MachineRepresentation::kBit;
47 case IrOpcode::kInt64AddWithOverflow:
48 case IrOpcode::kInt64SubWithOverflow:
49 CHECK_LE(index, static_cast<size_t>(1));
50 return index == 0 ? MachineRepresentation::kWord64
51 : MachineRepresentation::kBit;
52 case IrOpcode::kTryTruncateFloat32ToInt64:
53 case IrOpcode::kTryTruncateFloat64ToInt64:
54 case IrOpcode::kTryTruncateFloat32ToUint64:
55 case IrOpcode::kTryTruncateFloat64ToUint64:
56 CHECK_LE(index, static_cast<size_t>(1));
57 return index == 0 ? MachineRepresentation::kWord64
58 : MachineRepresentation::kBit;
59 case IrOpcode::kCall: {
60 CallDescriptor const* desc = CallDescriptorOf(input->op());
61 return desc->GetReturnType(index).representation();
62 }
63 default:
64 return MachineRepresentation::kNone;
65 }
66 }
67
68 void Run() {
69 auto blocks = schedule_->all_blocks();
70 for (BasicBlock* block : *blocks) {
71 for (size_t i = 0; i <= block->NodeCount(); ++i) {
72 Node const* node =
73 i < block->NodeCount() ? block->NodeAt(i) : block->control_input();
74 if (node == nullptr) {
75 DCHECK_EQ(block->NodeCount(), i);
76 break;
77 }
78 switch (node->opcode()) {
79 case IrOpcode::kParameter:
80 representation_vector_[node->id()] =
81 linkage_->GetParameterType(ParameterIndexOf(node->op()))
82 .representation();
83 break;
84 case IrOpcode::kProjection: {
85 representation_vector_[node->id()] = GetProjectionType(node);
86 } break;
87 case IrOpcode::kTypedStateValues:
88 representation_vector_[node->id()] = MachineRepresentation::kNone;
89 break;
90 case IrOpcode::kAtomicLoad:
91 case IrOpcode::kLoad:
92 case IrOpcode::kProtectedLoad:
93 representation_vector_[node->id()] =
94 LoadRepresentationOf(node->op()).representation();
95 break;
96 case IrOpcode::kCheckedLoad:
97 representation_vector_[node->id()] =
98 CheckedLoadRepresentationOf(node->op()).representation();
99 break;
100 case IrOpcode::kLoadStackPointer:
101 case IrOpcode::kLoadFramePointer:
102 case IrOpcode::kLoadParentFramePointer:
103 representation_vector_[node->id()] =
104 MachineType::PointerRepresentation();
105 break;
106 case IrOpcode::kPhi:
107 representation_vector_[node->id()] =
108 PhiRepresentationOf(node->op());
109 break;
110 case IrOpcode::kCall: {
111 CallDescriptor const* desc = CallDescriptorOf(node->op());
112 if (desc->ReturnCount() > 0) {
113 representation_vector_[node->id()] =
114 desc->GetReturnType(0).representation();
115 } else {
116 representation_vector_[node->id()] =
117 MachineRepresentation::kTagged;
118 }
119 break;
120 }
121 case IrOpcode::kUnalignedLoad:
122 representation_vector_[node->id()] =
123 UnalignedLoadRepresentationOf(node->op()).representation();
124 break;
125 case IrOpcode::kHeapConstant:
126 case IrOpcode::kNumberConstant:
127 case IrOpcode::kChangeBitToTagged:
128 case IrOpcode::kIfException:
129 case IrOpcode::kOsrValue:
130 case IrOpcode::kChangeInt32ToTagged:
131 case IrOpcode::kChangeUint32ToTagged:
132 case IrOpcode::kBitcastWordToTagged:
133 representation_vector_[node->id()] = MachineRepresentation::kTagged;
134 break;
135 case IrOpcode::kExternalConstant:
136 representation_vector_[node->id()] =
137 MachineType::PointerRepresentation();
138 break;
139 case IrOpcode::kBitcastTaggedToWord:
140 representation_vector_[node->id()] =
141 MachineType::PointerRepresentation();
142 break;
143 case IrOpcode::kBitcastWordToTaggedSigned:
144 representation_vector_[node->id()] =
145 MachineRepresentation::kTaggedSigned;
146 break;
147 case IrOpcode::kWord32Equal:
148 case IrOpcode::kInt32LessThan:
149 case IrOpcode::kInt32LessThanOrEqual:
150 case IrOpcode::kUint32LessThan:
151 case IrOpcode::kUint32LessThanOrEqual:
152 case IrOpcode::kWord64Equal:
153 case IrOpcode::kInt64LessThan:
154 case IrOpcode::kInt64LessThanOrEqual:
155 case IrOpcode::kUint64LessThan:
156 case IrOpcode::kUint64LessThanOrEqual:
157 case IrOpcode::kFloat32Equal:
158 case IrOpcode::kFloat32LessThan:
159 case IrOpcode::kFloat32LessThanOrEqual:
160 case IrOpcode::kFloat64Equal:
161 case IrOpcode::kFloat64LessThan:
162 case IrOpcode::kFloat64LessThanOrEqual:
163 case IrOpcode::kChangeTaggedToBit:
164 representation_vector_[node->id()] = MachineRepresentation::kBit;
165 break;
166 #define LABEL(opcode) case IrOpcode::k##opcode:
167 case IrOpcode::kTruncateInt64ToInt32:
168 case IrOpcode::kTruncateFloat32ToInt32:
169 case IrOpcode::kTruncateFloat32ToUint32:
170 case IrOpcode::kBitcastFloat32ToInt32:
171 case IrOpcode::kInt32x4ExtractLane:
172 case IrOpcode::kInt32Constant:
173 case IrOpcode::kRelocatableInt32Constant:
174 case IrOpcode::kTruncateFloat64ToWord32:
175 case IrOpcode::kTruncateFloat64ToUint32:
176 case IrOpcode::kChangeFloat64ToInt32:
177 case IrOpcode::kChangeFloat64ToUint32:
178 case IrOpcode::kRoundFloat64ToInt32:
179 case IrOpcode::kFloat64ExtractLowWord32:
180 case IrOpcode::kFloat64ExtractHighWord32:
181 MACHINE_UNOP_32_LIST(LABEL)
182 MACHINE_BINOP_32_LIST(LABEL) {
183 representation_vector_[node->id()] =
184 MachineRepresentation::kWord32;
185 }
186 break;
187 case IrOpcode::kChangeInt32ToInt64:
188 case IrOpcode::kChangeUint32ToUint64:
189 case IrOpcode::kInt64Constant:
190 case IrOpcode::kRelocatableInt64Constant:
191 case IrOpcode::kBitcastFloat64ToInt64:
192 MACHINE_BINOP_64_LIST(LABEL) {
193 representation_vector_[node->id()] =
194 MachineRepresentation::kWord64;
195 }
196 break;
197 case IrOpcode::kRoundInt32ToFloat32:
198 case IrOpcode::kRoundUint32ToFloat32:
199 case IrOpcode::kRoundInt64ToFloat32:
200 case IrOpcode::kRoundUint64ToFloat32:
201 case IrOpcode::kFloat32Constant:
202 case IrOpcode::kTruncateFloat64ToFloat32:
203 MACHINE_FLOAT32_BINOP_LIST(LABEL)
204 MACHINE_FLOAT32_UNOP_LIST(LABEL) {
205 representation_vector_[node->id()] =
206 MachineRepresentation::kFloat32;
207 }
208 break;
209 case IrOpcode::kRoundInt64ToFloat64:
210 case IrOpcode::kRoundUint64ToFloat64:
211 case IrOpcode::kChangeFloat32ToFloat64:
212 case IrOpcode::kChangeInt32ToFloat64:
213 case IrOpcode::kChangeUint32ToFloat64:
214 case IrOpcode::kFloat64Constant:
215 case IrOpcode::kFloat64SilenceNaN:
216 MACHINE_FLOAT64_BINOP_LIST(LABEL)
217 MACHINE_FLOAT64_UNOP_LIST(LABEL) {
218 representation_vector_[node->id()] =
219 MachineRepresentation::kFloat64;
220 }
221 break;
222 #undef LABEL
223 default:
224 break;
Jarin 2016/10/05 08:16:17 As discussed offline, it could be nicer to have a
225 }
226 }
227 }
228 }
229
230 Schedule const* const schedule_;
231 Linkage const* const linkage_;
232 ZoneVector<MachineRepresentation> representation_vector_;
233 };
234
235 class MachineRepresentationChecker {
236 public:
237 MachineRepresentationChecker(Schedule const* const schedule,
238 MachineRepresentationInferrer const* const typer)
239 : schedule_(schedule), typer_(typer) {}
240
241 void Run() {
242 BasicBlockVector const* blocks = schedule_->all_blocks();
243 for (BasicBlock* block : *blocks) {
244 for (size_t i = 0; i <= block->NodeCount(); ++i) {
245 Node const* node =
246 i < block->NodeCount() ? block->NodeAt(i) : block->control_input();
247 if (node == nullptr) {
248 DCHECK_EQ(block->NodeCount(), i);
249 break;
250 }
251 switch (node->opcode()) {
252 case IrOpcode::kCall:
253 case IrOpcode::kTailCall:
254 CheckCallInputs(node);
255 break;
256 case IrOpcode::kChangeBitToTagged:
257 CHECK_EQ(MachineRepresentation::kBit,
258 typer_->GetRepresentation(node->InputAt(0)));
259 break;
260 case IrOpcode::kChangeTaggedToBit:
261 CHECK_EQ(MachineRepresentation::kTagged,
262 typer_->GetRepresentation(node->InputAt(0)));
263 break;
264 case IrOpcode::kRoundInt64ToFloat64:
265 case IrOpcode::kRoundUint64ToFloat64:
266 case IrOpcode::kRoundInt64ToFloat32:
267 case IrOpcode::kRoundUint64ToFloat32:
268 case IrOpcode::kTruncateInt64ToInt32:
269 CheckValueInputForInt64Op(node, 0);
270 break;
271 case IrOpcode::kBitcastWordToTagged:
272 case IrOpcode::kBitcastWordToTaggedSigned:
273 CheckValueInputRepresentationIs(
274 node, 0, MachineType::PointerRepresentation());
275 break;
276 case IrOpcode::kBitcastTaggedToWord:
277 CheckValueInputIsTagged(node, 0);
278 break;
279 case IrOpcode::kTruncateFloat64ToWord32:
280 case IrOpcode::kTruncateFloat64ToUint32:
281 case IrOpcode::kTruncateFloat64ToFloat32:
282 case IrOpcode::kChangeFloat64ToInt32:
283 case IrOpcode::kChangeFloat64ToUint32:
284 case IrOpcode::kRoundFloat64ToInt32:
285 case IrOpcode::kFloat64ExtractLowWord32:
286 case IrOpcode::kFloat64ExtractHighWord32:
287 case IrOpcode::kBitcastFloat64ToInt64:
288 CheckValueInputForFloat64Op(node, 0);
289 break;
290 case IrOpcode::kWord64Equal:
291 CheckValueInputIsTaggedOrPointer(node, 0);
292 CheckValueInputRepresentationIs(
293 node, 1, typer_->GetRepresentation(node->InputAt(0)));
294 break;
295 case IrOpcode::kInt64LessThan:
296 case IrOpcode::kInt64LessThanOrEqual:
297 case IrOpcode::kUint64LessThan:
298 case IrOpcode::kUint64LessThanOrEqual:
299 CheckValueInputForInt64Op(node, 0);
300 CheckValueInputForInt64Op(node, 1);
301 break;
302 case IrOpcode::kInt32x4ExtractLane:
303 CheckValueInputRepresentationIs(node, 0,
304 MachineRepresentation::kSimd128);
305 break;
306 #define LABEL(opcode) case IrOpcode::k##opcode:
307 case IrOpcode::kChangeInt32ToTagged:
308 case IrOpcode::kChangeUint32ToTagged:
309 case IrOpcode::kChangeInt32ToFloat64:
310 case IrOpcode::kChangeUint32ToFloat64:
311 case IrOpcode::kRoundInt32ToFloat32:
312 case IrOpcode::kRoundUint32ToFloat32:
313 case IrOpcode::kChangeInt32ToInt64:
314 case IrOpcode::kChangeUint32ToUint64:
315 MACHINE_UNOP_32_LIST(LABEL) { CheckValueInputForInt32Op(node, 0); }
316 break;
317 case IrOpcode::kWord32Equal:
318 case IrOpcode::kInt32LessThan:
319 case IrOpcode::kInt32LessThanOrEqual:
320 case IrOpcode::kUint32LessThan:
321 case IrOpcode::kUint32LessThanOrEqual:
322 MACHINE_BINOP_32_LIST(LABEL) {
323 CheckValueInputForInt32Op(node, 0);
324 CheckValueInputForInt32Op(node, 1);
325 }
326 break;
327 MACHINE_BINOP_64_LIST(LABEL) {
328 CheckValueInputForInt64Op(node, 0);
329 CheckValueInputForInt64Op(node, 1);
330 }
331 break;
332 case IrOpcode::kFloat32Equal:
333 case IrOpcode::kFloat32LessThan:
334 case IrOpcode::kFloat32LessThanOrEqual:
335 MACHINE_FLOAT32_BINOP_LIST(LABEL) {
336 CheckValueInputForFloat32Op(node, 0);
337 CheckValueInputForFloat32Op(node, 1);
338 }
339 break;
340 case IrOpcode::kChangeFloat32ToFloat64:
341 case IrOpcode::kTruncateFloat32ToInt32:
342 case IrOpcode::kTruncateFloat32ToUint32:
343 case IrOpcode::kBitcastFloat32ToInt32:
344 MACHINE_FLOAT32_UNOP_LIST(LABEL) {
345 CheckValueInputForFloat32Op(node, 0);
346 }
347 break;
348 case IrOpcode::kFloat64Equal:
349 case IrOpcode::kFloat64LessThan:
350 case IrOpcode::kFloat64LessThanOrEqual:
351 MACHINE_FLOAT64_BINOP_LIST(LABEL) {
352 CheckValueInputForFloat64Op(node, 0);
353 CheckValueInputForFloat64Op(node, 1);
354 }
355 break;
356 case IrOpcode::kFloat64SilenceNaN:
357 MACHINE_FLOAT64_UNOP_LIST(LABEL) {
358 CheckValueInputForFloat64Op(node, 0);
359 }
360 break;
361 #undef LABEL
362 case IrOpcode::kParameter:
363 case IrOpcode::kProjection:
364 break;
365 case IrOpcode::kLoad:
366 case IrOpcode::kAtomicLoad:
367 CheckValueInputIsTaggedOrPointer(node, 0);
368 CheckValueInputRepresentationIs(
369 node, 1, MachineType::PointerRepresentation());
370 break;
371 case IrOpcode::kStore:
372 CheckValueInputIsTaggedOrPointer(node, 0);
373 CheckValueInputRepresentationIs(
374 node, 1, MachineType::PointerRepresentation());
375 switch (StoreRepresentationOf(node->op()).representation()) {
376 case MachineRepresentation::kTagged:
377 case MachineRepresentation::kTaggedPointer:
378 case MachineRepresentation::kTaggedSigned:
379 CheckValueInputIsTagged(node, 2);
380 break;
381 default:
382 CheckValueInputRepresentationIs(
383 node, 2,
384 StoreRepresentationOf(node->op()).representation());
385 }
386 break;
387 case IrOpcode::kAtomicStore:
388 CheckValueInputIsTaggedOrPointer(node, 0);
389 CheckValueInputRepresentationIs(
390 node, 1, MachineType::PointerRepresentation());
391 switch (AtomicStoreRepresentationOf(node->op())) {
392 case MachineRepresentation::kTagged:
393 case MachineRepresentation::kTaggedPointer:
394 case MachineRepresentation::kTaggedSigned:
395 CheckValueInputIsTagged(node, 2);
396 break;
397 default:
398 CheckValueInputRepresentationIs(
399 node, 2, AtomicStoreRepresentationOf(node->op()));
400 }
401 break;
402 case IrOpcode::kPhi:
403 switch (typer_->GetRepresentation(node)) {
404 case MachineRepresentation::kTagged:
405 case MachineRepresentation::kTaggedPointer:
406 case MachineRepresentation::kTaggedSigned:
407 for (int i = 0; i < node->op()->ValueInputCount(); ++i) {
408 CheckValueInputIsTagged(node, i);
409 }
410 break;
411 default:
412 for (int i = 0; i < node->op()->ValueInputCount(); ++i) {
413 CheckValueInputRepresentationIs(
414 node, i, typer_->GetRepresentation(node));
415 }
416 break;
417 }
418 break;
419 case IrOpcode::kBranch:
420 case IrOpcode::kSwitch:
421 CheckValueInputForInt32Op(node, 0);
422 break;
423 case IrOpcode::kReturn:
424 // TODO(epertoso): use the linkage to determine which tipe we
425 // should have here.
426 break;
427 case IrOpcode::kTypedStateValues:
428 case IrOpcode::kFrameState:
429 break;
430 default:
431 if (node->op()->ValueInputCount() != 0) {
432 std::stringstream str;
433 str << "Node #" << node->id() << ":" << *node->op()
434 << " in the machine graph is not being checked.";
435 FATAL(str.str().c_str());
436 }
437 break;
438 }
439 }
440 }
441 }
442
443 private:
444 void CheckValueInputRepresentationIs(Node const* node, int index,
445 MachineRepresentation representation) {
446 Node const* input = node->InputAt(index);
447 if (typer_->GetRepresentation(input) != representation) {
448 std::stringstream str;
449 str << "TypeError: node #" << node->id() << ":" << *node->op()
450 << " uses node #" << input->id() << ":" << *input->op()
451 << " which doesn't have a " << MachineReprToString(representation)
452 << " representation.";
453 FATAL(str.str().c_str());
454 }
455 }
456
457 void CheckValueInputIsTagged(Node const* node, int index) {
458 Node const* input = node->InputAt(index);
459 switch (typer_->GetRepresentation(input)) {
460 case MachineRepresentation::kTagged:
461 case MachineRepresentation::kTaggedPointer:
462 case MachineRepresentation::kTaggedSigned:
463 return;
464 default:
465 break;
466 }
467 std::ostringstream str;
468 str << "TypeError: node #" << node->id() << ":" << *node->op()
469 << " uses node #" << input->id() << ":" << *input->op()
470 << " which doesn't have a tagged representation.";
471 FATAL(str.str().c_str());
472 }
473
474 void CheckValueInputIsTaggedOrPointer(Node const* node, int index) {
475 Node const* input = node->InputAt(index);
476 switch (typer_->GetRepresentation(input)) {
477 case MachineRepresentation::kTagged:
478 case MachineRepresentation::kTaggedPointer:
479 case MachineRepresentation::kTaggedSigned:
480 return;
481 default:
482 break;
483 }
484 if (typer_->GetRepresentation(input) !=
485 MachineType::PointerRepresentation()) {
486 std::ostringstream str;
487 str << "TypeError: node #" << node->id() << ":" << *node->op()
488 << " uses node #" << input->id() << ":" << *input->op()
489 << " which doesn't have a tagged or pointer representation.";
490 FATAL(str.str().c_str());
491 }
492 }
493
494 void CheckValueInputForInt32Op(Node const* node, int index) {
495 Node const* input = node->InputAt(index);
496 switch (typer_->GetRepresentation(input)) {
497 case MachineRepresentation::kBit:
498 case MachineRepresentation::kWord8:
499 case MachineRepresentation::kWord16:
500 case MachineRepresentation::kWord32:
501 return;
502 case MachineRepresentation::kNone: {
503 std::ostringstream str;
504 str << "TypeError: node #" << input->id() << ":" << *input->op()
505 << " is untyped.";
506 FATAL(str.str().c_str());
507 break;
508 }
509 default:
510 break;
511 }
512 std::ostringstream str;
513 str << "TypeError: node #" << node->id() << ":" << *node->op()
514 << " uses node #" << input->id() << ":" << *input->op()
515 << " which doesn't have an int32-compatible representation.";
516 FATAL(str.str().c_str());
517 }
518
519 void CheckValueInputForInt64Op(Node const* node, int index) {
520 Node const* input = node->InputAt(index);
521 switch (typer_->GetRepresentation(input)) {
522 case MachineRepresentation::kWord64:
523 return;
524 case MachineRepresentation::kNone: {
525 std::ostringstream str;
526 str << "TypeError: node #" << input->id() << ":" << *input->op()
527 << " is untyped.";
528 FATAL(str.str().c_str());
529 break;
530 }
531
532 default:
533 break;
534 }
535 std::ostringstream str;
536 str << "TypeError: node #" << node->id() << ":" << *node->op()
537 << " uses node #" << input->id() << ":" << *input->op()
538 << " which doesn't have a kWord64 representation.";
539 FATAL(str.str().c_str());
540 }
541
542 void CheckValueInputForFloat32Op(Node const* node, int index) {
543 Node const* input = node->InputAt(index);
544 if (MachineRepresentation::kFloat32 == typer_->GetRepresentation(input)) {
545 return;
546 }
547 std::ostringstream str;
548 str << "TypeError: node #" << node->id() << ":" << *node->op()
549 << " uses node #" << input->id() << ":" << *input->op()
550 << " which doesn't have a kFloat32 representation.";
551 FATAL(str.str().c_str());
552 }
553
554 void CheckValueInputForFloat64Op(Node const* node, int index) {
555 Node const* input = node->InputAt(index);
556 if (MachineRepresentation::kFloat64 == typer_->GetRepresentation(input)) {
557 return;
558 }
559 std::ostringstream str;
560 str << "TypeError: node #" << node->id() << ":" << *node->op()
561 << " uses node #" << input->id() << ":" << *input->op()
562 << " which doesn't have a kFloat64 representation.";
563 FATAL(str.str().c_str());
564 }
565
566 void CheckCallInputs(Node const* node) {
567 CallDescriptor const* desc = CallDescriptorOf(node->op());
568 std::ostringstream str;
569 bool should_log_error = false;
570 for (size_t i = 0; i < desc->InputCount(); ++i) {
571 Node const* input = node->InputAt(static_cast<int>(i));
572 MachineRepresentation const input_type = typer_->GetRepresentation(input);
573 MachineRepresentation const expected_input_type =
574 desc->GetInputType(i).representation();
575 if (!IsCompatible(expected_input_type, input_type)) {
576 if (!should_log_error) {
577 should_log_error = true;
578 str << "TypeError: node #" << node->id() << ":" << *node->op()
579 << " has wrong type for:" << std::endl;
580 } else {
581 str << std::endl;
582 }
583 str << " * input " << i << " (" << input->id() << ":" << *input->op()
584 << ") doesn't have a " << MachineReprToString(expected_input_type)
585 << " representation.";
586 }
587 }
588 if (should_log_error) {
589 FATAL(str.str().c_str());
590 }
591 }
592
593 bool Intersect(MachineRepresentation lhs, MachineRepresentation rhs) {
594 return (GetRepresentationProperties(lhs) &
595 GetRepresentationProperties(rhs)) != 0;
596 }
597
598 enum RepresentationProperties { kIsPointer = 1, kIsTagged = 2 };
599
600 int GetRepresentationProperties(MachineRepresentation representation) {
601 switch (representation) {
602 case MachineRepresentation::kTagged:
603 case MachineRepresentation::kTaggedPointer:
604 return kIsPointer | kIsTagged;
605 case MachineRepresentation::kTaggedSigned:
606 return kIsTagged;
607 case MachineRepresentation::kWord32:
608 return MachineRepresentation::kWord32 ==
609 MachineType::PointerRepresentation()
610 ? kIsPointer
611 : 0;
612 case MachineRepresentation::kWord64:
613 return MachineRepresentation::kWord64 ==
614 MachineType::PointerRepresentation()
615 ? kIsPointer
616 : 0;
617 default:
618 return 0;
619 }
620 }
621
622 bool IsCompatible(MachineRepresentation expected,
623 MachineRepresentation actual) {
624 switch (expected) {
625 case MachineRepresentation::kTagged:
626 return (actual == MachineRepresentation::kTagged ||
627 actual == MachineRepresentation::kTaggedSigned ||
628 actual == MachineRepresentation::kTaggedPointer);
629 case MachineRepresentation::kTaggedSigned:
630 case MachineRepresentation::kTaggedPointer:
631 case MachineRepresentation::kFloat32:
632 case MachineRepresentation::kFloat64:
633 case MachineRepresentation::kSimd128:
634 case MachineRepresentation::kBit:
635 case MachineRepresentation::kWord8:
636 case MachineRepresentation::kWord16:
637 case MachineRepresentation::kWord64:
638 return expected == actual;
639 break;
640 case MachineRepresentation::kWord32:
641 return (actual == MachineRepresentation::kBit ||
642 actual == MachineRepresentation::kWord8 ||
643 actual == MachineRepresentation::kWord16 ||
644 actual == MachineRepresentation::kWord32);
645 case MachineRepresentation::kNone:
646 UNREACHABLE();
647 }
648 return false;
649 }
650
651 Schedule const* const schedule_;
652 MachineRepresentationInferrer const* const typer_;
653 };
654
655 } // namespace
656
657 void MachineGraphVerifier::Run(Graph* graph, Schedule const* const schedule,
658 Linkage* linkage, Zone* temp_zone) {
659 MachineRepresentationInferrer representation_inferrer(schedule, graph,
660 linkage, temp_zone);
661 MachineRepresentationChecker checker(schedule, &representation_inferrer);
662 checker.Run();
663 }
664
665 } // namespace compiler
666 } // namespace internal
667 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/machine-graph-verifier.h ('k') | src/compiler/machine-operator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698