5 #include "src/compiler/machine-graph-verifier.h" 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" 22 class MachineRepresentationInferrer {
24 MachineRepresentationInferrer(Schedule
const* schedule, Graph
const* graph,
25 Linkage* linkage, Zone* zone)
26 : schedule_(schedule),
28 representation_vector_(graph->NodeCount(), MachineRepresentation::
kNone,
33 CallDescriptor* call_descriptor()
const {
34 return linkage_->GetIncomingDescriptor();
37 MachineRepresentation GetRepresentation(Node
const* node)
const {
38 return representation_vector_.at(node->id());
42 MachineRepresentation GetProjectionType(Node
const* projection) {
43 size_t index = ProjectionIndexOf(projection->op());
44 Node* input = projection->InputAt(0);
45 switch (input->opcode()) {
46 case IrOpcode::kInt32AddWithOverflow:
47 case IrOpcode::kInt32SubWithOverflow:
48 case IrOpcode::kInt32MulWithOverflow:
49 CHECK_LE(index, static_cast<size_t>(1));
50 return index == 0 ? MachineRepresentation::kWord32
51 : MachineRepresentation::kBit;
52 case IrOpcode::kInt64AddWithOverflow:
53 case IrOpcode::kInt64SubWithOverflow:
54 CHECK_LE(index, static_cast<size_t>(1));
55 return index == 0 ? MachineRepresentation::kWord64
56 : MachineRepresentation::kBit;
57 case IrOpcode::kTryTruncateFloat32ToInt64:
58 case IrOpcode::kTryTruncateFloat64ToInt64:
59 case IrOpcode::kTryTruncateFloat32ToUint64:
60 CHECK_LE(index, static_cast<size_t>(1));
61 return index == 0 ? MachineRepresentation::kWord64
62 : MachineRepresentation::kBit;
64 case IrOpcode::kCallWithCallerSavedRegisters: {
65 auto call_descriptor = CallDescriptorOf(input->op());
66 return call_descriptor->GetReturnType(index).representation();
68 case IrOpcode::kWord32AtomicPairLoad:
69 case IrOpcode::kWord32AtomicPairAdd:
70 case IrOpcode::kWord32AtomicPairSub:
71 case IrOpcode::kWord32AtomicPairAnd:
72 case IrOpcode::kWord32AtomicPairOr:
73 case IrOpcode::kWord32AtomicPairXor:
74 case IrOpcode::kWord32AtomicPairExchange:
75 case IrOpcode::kWord32AtomicPairCompareExchange:
76 CHECK_LE(index, static_cast<size_t>(1));
77 return MachineRepresentation::kWord32;
79 return MachineRepresentation::kNone;
83 MachineRepresentation PromoteRepresentation(MachineRepresentation rep) {
85 case MachineRepresentation::kWord8:
86 case MachineRepresentation::kWord16:
87 case MachineRepresentation::kWord32:
88 return MachineRepresentation::kWord32;
96 auto blocks = schedule_->all_blocks();
97 for (BasicBlock* block : *blocks) {
98 current_block_ = block;
99 for (
size_t i = 0;
i <= block->NodeCount(); ++
i) {
101 i < block->NodeCount() ? block->NodeAt(
i) : block->control_input();
102 if (node ==
nullptr) {
103 DCHECK_EQ(block->NodeCount(),
i);
106 switch (node->opcode()) {
107 case IrOpcode::kParameter:
108 representation_vector_[node->id()] =
109 linkage_->GetParameterType(ParameterIndexOf(node->op()))
112 case IrOpcode::kReturn: {
113 representation_vector_[node->id()] = PromoteRepresentation(
114 linkage_->GetReturnType().representation());
117 case IrOpcode::kProjection: {
118 representation_vector_[node->id()] = GetProjectionType(node);
120 case IrOpcode::kTypedStateValues:
121 representation_vector_[node->id()] = MachineRepresentation::kNone;
123 case IrOpcode::kWord32AtomicLoad:
124 case IrOpcode::kWord64AtomicLoad:
125 case IrOpcode::kLoad:
126 case IrOpcode::kProtectedLoad:
127 case IrOpcode::kPoisonedLoad:
128 representation_vector_[node->id()] = PromoteRepresentation(
129 LoadRepresentationOf(node->op()).representation());
131 case IrOpcode::kLoadStackPointer:
132 case IrOpcode::kLoadFramePointer:
133 case IrOpcode::kLoadParentFramePointer:
134 representation_vector_[node->id()] =
135 MachineType::PointerRepresentation();
137 case IrOpcode::kUnalignedLoad:
138 representation_vector_[node->id()] = PromoteRepresentation(
139 LoadRepresentationOf(node->op()).representation());
142 representation_vector_[node->id()] =
143 PhiRepresentationOf(node->op());
145 case IrOpcode::kCall:
146 case IrOpcode::kCallWithCallerSavedRegisters: {
147 auto call_descriptor = CallDescriptorOf(node->op());
148 if (call_descriptor->ReturnCount() > 0) {
149 representation_vector_[node->id()] =
150 call_descriptor->GetReturnType(0).representation();
152 representation_vector_[node->id()] =
153 MachineRepresentation::kTagged;
157 case IrOpcode::kWord32AtomicStore:
158 case IrOpcode::kWord64AtomicStore:
159 representation_vector_[node->id()] =
160 PromoteRepresentation(AtomicStoreRepresentationOf(node->op()));
162 case IrOpcode::kWord32AtomicPairLoad:
163 case IrOpcode::kWord32AtomicPairStore:
164 case IrOpcode::kWord32AtomicPairAdd:
165 case IrOpcode::kWord32AtomicPairSub:
166 case IrOpcode::kWord32AtomicPairAnd:
167 case IrOpcode::kWord32AtomicPairOr:
168 case IrOpcode::kWord32AtomicPairXor:
169 case IrOpcode::kWord32AtomicPairExchange:
170 case IrOpcode::kWord32AtomicPairCompareExchange:
171 representation_vector_[node->id()] = MachineRepresentation::kWord32;
173 case IrOpcode::kWord32AtomicExchange:
174 case IrOpcode::kWord32AtomicCompareExchange:
175 case IrOpcode::kWord32AtomicAdd:
176 case IrOpcode::kWord32AtomicSub:
177 case IrOpcode::kWord32AtomicAnd:
178 case IrOpcode::kWord32AtomicOr:
179 case IrOpcode::kWord32AtomicXor:
180 case IrOpcode::kWord64AtomicExchange:
181 case IrOpcode::kWord64AtomicCompareExchange:
182 case IrOpcode::kWord64AtomicAdd:
183 case IrOpcode::kWord64AtomicSub:
184 case IrOpcode::kWord64AtomicAnd:
185 case IrOpcode::kWord64AtomicOr:
186 case IrOpcode::kWord64AtomicXor:
187 representation_vector_[node->id()] = PromoteRepresentation(
188 AtomicOpType(node->op()).representation());
190 case IrOpcode::kStore:
191 case IrOpcode::kProtectedStore:
192 representation_vector_[node->id()] = PromoteRepresentation(
193 StoreRepresentationOf(node->op()).representation());
195 case IrOpcode::kUnalignedStore:
196 representation_vector_[node->id()] = PromoteRepresentation(
197 UnalignedStoreRepresentationOf(node->op()));
199 case IrOpcode::kHeapConstant:
200 case IrOpcode::kNumberConstant:
201 case IrOpcode::kDelayedStringConstant:
202 case IrOpcode::kChangeBitToTagged:
203 case IrOpcode::kIfException:
204 case IrOpcode::kOsrValue:
205 case IrOpcode::kChangeInt32ToTagged:
206 case IrOpcode::kChangeUint32ToTagged:
207 case IrOpcode::kBitcastWordToTagged:
208 case IrOpcode::kTaggedPoisonOnSpeculation:
209 representation_vector_[node->id()] = MachineRepresentation::kTagged;
211 case IrOpcode::kWord32PoisonOnSpeculation:
212 representation_vector_[node->id()] = MachineRepresentation::kWord32;
214 case IrOpcode::kWord64PoisonOnSpeculation:
215 representation_vector_[node->id()] = MachineRepresentation::kWord64;
217 case IrOpcode::kExternalConstant:
218 representation_vector_[node->id()] =
219 MachineType::PointerRepresentation();
221 case IrOpcode::kBitcastTaggedToWord:
222 representation_vector_[node->id()] =
223 MachineType::PointerRepresentation();
225 case IrOpcode::kBitcastWordToTaggedSigned:
226 representation_vector_[node->id()] =
227 MachineRepresentation::kTaggedSigned;
229 case IrOpcode::kWord32Equal:
230 case IrOpcode::kInt32LessThan:
231 case IrOpcode::kInt32LessThanOrEqual:
232 case IrOpcode::kUint32LessThan:
233 case IrOpcode::kUint32LessThanOrEqual:
234 case IrOpcode::kWord64Equal:
235 case IrOpcode::kInt64LessThan:
236 case IrOpcode::kInt64LessThanOrEqual:
237 case IrOpcode::kUint64LessThan:
238 case IrOpcode::kUint64LessThanOrEqual:
239 case IrOpcode::kFloat32Equal:
240 case IrOpcode::kFloat32LessThan:
241 case IrOpcode::kFloat32LessThanOrEqual:
242 case IrOpcode::kFloat64Equal:
243 case IrOpcode::kFloat64LessThan:
244 case IrOpcode::kFloat64LessThanOrEqual:
245 case IrOpcode::kChangeTaggedToBit:
246 representation_vector_[node->id()] = MachineRepresentation::kBit;
248 #define LABEL(opcode) case IrOpcode::k##opcode: 249 case IrOpcode::kTruncateInt64ToInt32:
250 case IrOpcode::kTruncateFloat32ToInt32:
251 case IrOpcode::kTruncateFloat32ToUint32:
252 case IrOpcode::kBitcastFloat32ToInt32:
253 case IrOpcode::kI32x4ExtractLane:
254 case IrOpcode::kI16x8ExtractLane:
255 case IrOpcode::kI8x16ExtractLane:
256 case IrOpcode::kInt32Constant:
257 case IrOpcode::kRelocatableInt32Constant:
258 case IrOpcode::kTruncateFloat64ToWord32:
259 case IrOpcode::kTruncateFloat64ToUint32:
260 case IrOpcode::kChangeFloat64ToInt32:
261 case IrOpcode::kChangeFloat64ToUint32:
262 case IrOpcode::kRoundFloat64ToInt32:
263 case IrOpcode::kFloat64ExtractLowWord32:
264 case IrOpcode::kFloat64ExtractHighWord32:
265 MACHINE_UNOP_32_LIST(LABEL)
266 MACHINE_BINOP_32_LIST(LABEL) {
267 representation_vector_[node->id()] =
268 MachineRepresentation::kWord32;
271 case IrOpcode::kChangeInt32ToInt64:
272 case IrOpcode::kChangeUint32ToUint64:
273 case IrOpcode::kInt64Constant:
274 case IrOpcode::kRelocatableInt64Constant:
275 case IrOpcode::kBitcastFloat64ToInt64:
276 case IrOpcode::kChangeFloat64ToUint64:
277 MACHINE_BINOP_64_LIST(LABEL) {
278 representation_vector_[node->id()] =
279 MachineRepresentation::kWord64;
282 case IrOpcode::kRoundInt32ToFloat32:
283 case IrOpcode::kRoundUint32ToFloat32:
284 case IrOpcode::kRoundInt64ToFloat32:
285 case IrOpcode::kRoundUint64ToFloat32:
286 case IrOpcode::kBitcastInt32ToFloat32:
287 case IrOpcode::kFloat32Constant:
288 case IrOpcode::kTruncateFloat64ToFloat32:
289 MACHINE_FLOAT32_BINOP_LIST(LABEL)
290 MACHINE_FLOAT32_UNOP_LIST(LABEL) {
291 representation_vector_[node->id()] =
292 MachineRepresentation::kFloat32;
295 case IrOpcode::kRoundInt64ToFloat64:
296 case IrOpcode::kRoundUint64ToFloat64:
297 case IrOpcode::kChangeFloat32ToFloat64:
298 case IrOpcode::kChangeInt32ToFloat64:
299 case IrOpcode::kChangeUint32ToFloat64:
300 case IrOpcode::kFloat64InsertLowWord32:
301 case IrOpcode::kFloat64InsertHighWord32:
302 case IrOpcode::kFloat64Constant:
303 case IrOpcode::kFloat64SilenceNaN:
304 MACHINE_FLOAT64_BINOP_LIST(LABEL)
305 MACHINE_FLOAT64_UNOP_LIST(LABEL) {
306 representation_vector_[node->id()] =
307 MachineRepresentation::kFloat64;
310 case IrOpcode::kI32x4ReplaceLane:
311 case IrOpcode::kI32x4Splat:
312 representation_vector_[node->id()] =
313 MachineRepresentation::kSimd128;
323 Schedule
const*
const schedule_;
324 Linkage
const*
const linkage_;
325 ZoneVector<MachineRepresentation> representation_vector_;
326 BasicBlock* current_block_;
329 class MachineRepresentationChecker {
331 MachineRepresentationChecker(
332 Schedule
const*
const schedule,
333 MachineRepresentationInferrer
const*
const inferrer,
bool is_stub,
335 : schedule_(schedule),
339 current_block_(nullptr) {}
342 BasicBlockVector
const* blocks = schedule_->all_blocks();
343 for (BasicBlock* block : *blocks) {
344 current_block_ = block;
345 for (
size_t i = 0;
i <= block->NodeCount(); ++
i) {
347 i < block->NodeCount() ? block->NodeAt(
i) : block->control_input();
348 if (node ==
nullptr) {
349 DCHECK_EQ(block->NodeCount(),
i);
352 switch (node->opcode()) {
353 case IrOpcode::kCall:
354 case IrOpcode::kCallWithCallerSavedRegisters:
355 case IrOpcode::kTailCall:
356 CheckCallInputs(node);
358 case IrOpcode::kChangeBitToTagged:
359 CHECK_EQ(MachineRepresentation::kBit,
360 inferrer_->GetRepresentation(node->InputAt(0)));
362 case IrOpcode::kChangeTaggedToBit:
363 CHECK_EQ(MachineRepresentation::kTagged,
364 inferrer_->GetRepresentation(node->InputAt(0)));
366 case IrOpcode::kRoundInt64ToFloat64:
367 case IrOpcode::kRoundUint64ToFloat64:
368 case IrOpcode::kRoundInt64ToFloat32:
369 case IrOpcode::kRoundUint64ToFloat32:
370 case IrOpcode::kTruncateInt64ToInt32:
371 CheckValueInputForInt64Op(node, 0);
373 case IrOpcode::kBitcastWordToTagged:
374 case IrOpcode::kBitcastWordToTaggedSigned:
375 CheckValueInputRepresentationIs(
376 node, 0, MachineType::PointerRepresentation());
378 case IrOpcode::kWord32PoisonOnSpeculation:
379 CheckValueInputRepresentationIs(node, 0,
380 MachineRepresentation::kWord32);
382 case IrOpcode::kWord64PoisonOnSpeculation:
383 CheckValueInputRepresentationIs(node, 0,
384 MachineRepresentation::kWord64);
386 case IrOpcode::kBitcastTaggedToWord:
387 case IrOpcode::kTaggedPoisonOnSpeculation:
388 CheckValueInputIsTagged(node, 0);
390 case IrOpcode::kTruncateFloat64ToWord32:
391 case IrOpcode::kTruncateFloat64ToUint32:
392 case IrOpcode::kTruncateFloat64ToFloat32:
393 case IrOpcode::kChangeFloat64ToInt32:
394 case IrOpcode::kChangeFloat64ToUint32:
395 case IrOpcode::kRoundFloat64ToInt32:
396 case IrOpcode::kFloat64ExtractLowWord32:
397 case IrOpcode::kFloat64ExtractHighWord32:
398 case IrOpcode::kBitcastFloat64ToInt64:
399 case IrOpcode::kTryTruncateFloat64ToInt64:
400 CheckValueInputForFloat64Op(node, 0);
402 case IrOpcode::kWord64Equal:
404 CheckValueInputIsTaggedOrPointer(node, 0);
405 CheckValueInputIsTaggedOrPointer(node, 1);
407 CheckValueInputRepresentationIs(
408 node, 1, inferrer_->GetRepresentation(node->InputAt(0)));
411 CheckValueInputForInt64Op(node, 0);
412 CheckValueInputForInt64Op(node, 1);
415 case IrOpcode::kInt64LessThan:
416 case IrOpcode::kInt64LessThanOrEqual:
417 case IrOpcode::kUint64LessThan:
418 case IrOpcode::kUint64LessThanOrEqual:
419 CheckValueInputForInt64Op(node, 0);
420 CheckValueInputForInt64Op(node, 1);
422 case IrOpcode::kI32x4ExtractLane:
423 case IrOpcode::kI16x8ExtractLane:
424 case IrOpcode::kI8x16ExtractLane:
425 CheckValueInputRepresentationIs(node, 0,
426 MachineRepresentation::kSimd128);
428 case IrOpcode::kI32x4ReplaceLane:
429 CheckValueInputRepresentationIs(node, 0,
430 MachineRepresentation::kSimd128);
431 CheckValueInputForInt32Op(node, 1);
433 case IrOpcode::kI32x4Splat:
434 CheckValueInputForInt32Op(node, 0);
436 #define LABEL(opcode) case IrOpcode::k##opcode: 437 case IrOpcode::kChangeInt32ToTagged:
438 case IrOpcode::kChangeUint32ToTagged:
439 case IrOpcode::kChangeInt32ToFloat64:
440 case IrOpcode::kChangeUint32ToFloat64:
441 case IrOpcode::kRoundInt32ToFloat32:
442 case IrOpcode::kRoundUint32ToFloat32:
443 case IrOpcode::kBitcastInt32ToFloat32:
444 case IrOpcode::kChangeInt32ToInt64:
445 case IrOpcode::kChangeUint32ToUint64:
446 MACHINE_UNOP_32_LIST(LABEL) { CheckValueInputForInt32Op(node, 0); }
448 case IrOpcode::kWord32Equal:
450 CheckValueInputIsTaggedOrPointer(node, 0);
451 CheckValueInputIsTaggedOrPointer(node, 1);
453 CheckValueInputRepresentationIs(
454 node, 1, inferrer_->GetRepresentation(node->InputAt(0)));
457 CheckValueInputForInt32Op(node, 0);
458 CheckValueInputForInt32Op(node, 1);
462 case IrOpcode::kInt32LessThan:
463 case IrOpcode::kInt32LessThanOrEqual:
464 case IrOpcode::kUint32LessThan:
465 case IrOpcode::kUint32LessThanOrEqual:
466 MACHINE_BINOP_32_LIST(LABEL) {
467 CheckValueInputForInt32Op(node, 0);
468 CheckValueInputForInt32Op(node, 1);
471 MACHINE_BINOP_64_LIST(LABEL) {
472 CheckValueInputForInt64Op(node, 0);
473 CheckValueInputForInt64Op(node, 1);
476 case IrOpcode::kFloat32Equal:
477 case IrOpcode::kFloat32LessThan:
478 case IrOpcode::kFloat32LessThanOrEqual:
479 MACHINE_FLOAT32_BINOP_LIST(LABEL) {
480 CheckValueInputForFloat32Op(node, 0);
481 CheckValueInputForFloat32Op(node, 1);
484 case IrOpcode::kChangeFloat32ToFloat64:
485 case IrOpcode::kTruncateFloat32ToInt32:
486 case IrOpcode::kTruncateFloat32ToUint32:
487 case IrOpcode::kBitcastFloat32ToInt32:
488 MACHINE_FLOAT32_UNOP_LIST(LABEL) {
489 CheckValueInputForFloat32Op(node, 0);
492 case IrOpcode::kFloat64Equal:
493 case IrOpcode::kFloat64LessThan:
494 case IrOpcode::kFloat64LessThanOrEqual:
495 MACHINE_FLOAT64_BINOP_LIST(LABEL) {
496 CheckValueInputForFloat64Op(node, 0);
497 CheckValueInputForFloat64Op(node, 1);
500 case IrOpcode::kFloat64SilenceNaN:
501 case IrOpcode::kChangeFloat64ToUint64:
502 MACHINE_FLOAT64_UNOP_LIST(LABEL) {
503 CheckValueInputForFloat64Op(node, 0);
507 case IrOpcode::kFloat64InsertLowWord32:
508 case IrOpcode::kFloat64InsertHighWord32:
509 CheckValueInputForFloat64Op(node, 0);
510 CheckValueInputForInt32Op(node, 1);
512 case IrOpcode::kParameter:
513 case IrOpcode::kProjection:
515 case IrOpcode::kDebugAbort:
516 CheckValueInputIsTagged(node, 0);
518 case IrOpcode::kLoad:
519 case IrOpcode::kWord32AtomicLoad:
520 case IrOpcode::kWord32AtomicPairLoad:
521 case IrOpcode::kWord64AtomicLoad:
522 case IrOpcode::kPoisonedLoad:
523 CheckValueInputIsTaggedOrPointer(node, 0);
524 CheckValueInputRepresentationIs(
525 node, 1, MachineType::PointerRepresentation());
527 case IrOpcode::kWord32AtomicPairAdd:
528 case IrOpcode::kWord32AtomicPairSub:
529 case IrOpcode::kWord32AtomicPairAnd:
530 case IrOpcode::kWord32AtomicPairOr:
531 case IrOpcode::kWord32AtomicPairXor:
532 case IrOpcode::kWord32AtomicPairStore:
533 case IrOpcode::kWord32AtomicPairExchange:
534 CheckValueInputRepresentationIs(node, 3,
535 MachineRepresentation::kWord32);
537 case IrOpcode::kStore:
538 case IrOpcode::kWord32AtomicStore:
539 case IrOpcode::kWord32AtomicExchange:
540 case IrOpcode::kWord32AtomicAdd:
541 case IrOpcode::kWord32AtomicSub:
542 case IrOpcode::kWord32AtomicAnd:
543 case IrOpcode::kWord32AtomicOr:
544 case IrOpcode::kWord32AtomicXor:
545 case IrOpcode::kWord64AtomicStore:
546 case IrOpcode::kWord64AtomicExchange:
547 case IrOpcode::kWord64AtomicAdd:
548 case IrOpcode::kWord64AtomicSub:
549 case IrOpcode::kWord64AtomicAnd:
550 case IrOpcode::kWord64AtomicOr:
551 case IrOpcode::kWord64AtomicXor:
552 CheckValueInputIsTaggedOrPointer(node, 0);
553 CheckValueInputRepresentationIs(
554 node, 1, MachineType::PointerRepresentation());
555 switch (inferrer_->GetRepresentation(node)) {
556 case MachineRepresentation::kTagged:
557 case MachineRepresentation::kTaggedPointer:
558 case MachineRepresentation::kTaggedSigned:
559 CheckValueInputIsTagged(node, 2);
562 CheckValueInputRepresentationIs(
563 node, 2, inferrer_->GetRepresentation(node));
566 case IrOpcode::kWord32AtomicPairCompareExchange:
567 CheckValueInputRepresentationIs(node, 4,
568 MachineRepresentation::kWord32);
569 CheckValueInputRepresentationIs(node, 5,
570 MachineRepresentation::kWord32);
572 case IrOpcode::kWord32AtomicCompareExchange:
573 case IrOpcode::kWord64AtomicCompareExchange:
574 CheckValueInputIsTaggedOrPointer(node, 0);
575 CheckValueInputRepresentationIs(
576 node, 1, MachineType::PointerRepresentation());
577 switch (inferrer_->GetRepresentation(node)) {
578 case MachineRepresentation::kTagged:
579 case MachineRepresentation::kTaggedPointer:
580 case MachineRepresentation::kTaggedSigned:
581 CheckValueInputIsTagged(node, 2);
582 CheckValueInputIsTagged(node, 3);
585 CheckValueInputRepresentationIs(
586 node, 2, inferrer_->GetRepresentation(node));
587 CheckValueInputRepresentationIs(
588 node, 3, inferrer_->GetRepresentation(node));
592 switch (inferrer_->GetRepresentation(node)) {
593 case MachineRepresentation::kTagged:
594 case MachineRepresentation::kTaggedPointer:
595 case MachineRepresentation::kTaggedSigned:
596 for (
int i = 0;
i < node->op()->ValueInputCount(); ++
i) {
597 CheckValueInputIsTagged(node,
i);
600 case MachineRepresentation::kWord32:
601 for (
int i = 0;
i < node->op()->ValueInputCount(); ++
i) {
602 CheckValueInputForInt32Op(node,
i);
606 for (
int i = 0;
i < node->op()->ValueInputCount(); ++
i) {
607 CheckValueInputRepresentationIs(
608 node,
i, inferrer_->GetRepresentation(node));
613 case IrOpcode::kBranch:
614 case IrOpcode::kSwitch:
615 CheckValueInputForInt32Op(node, 0);
617 case IrOpcode::kReturn: {
623 size_t return_count = inferrer_->call_descriptor()->ReturnCount();
624 for (
size_t i = 0;
i < return_count;
i++) {
625 MachineType type = inferrer_->call_descriptor()->GetReturnType(
i);
626 int input_index =
static_cast<int>(
i + 1);
627 switch (type.representation()) {
628 case MachineRepresentation::kTagged:
629 case MachineRepresentation::kTaggedPointer:
630 case MachineRepresentation::kTaggedSigned:
631 CheckValueInputIsTagged(node, input_index);
633 case MachineRepresentation::kWord32:
634 CheckValueInputForInt32Op(node, input_index);
637 CheckValueInputRepresentationIs(node, input_index,
638 type.representation());
644 case IrOpcode::kThrow:
645 case IrOpcode::kTypedStateValues:
646 case IrOpcode::kFrameState:
649 if (node->op()->ValueInputCount() != 0) {
650 std::stringstream str;
651 str <<
"Node #" << node->id() <<
":" << *node->op()
652 <<
" in the machine graph is not being checked.";
653 PrintDebugHelp(str, node);
654 FATAL(
"%s", str.str().c_str());
664 return MachineType::PointerRepresentation() ==
665 MachineRepresentation::kWord32;
668 return MachineType::PointerRepresentation() ==
669 MachineRepresentation::kWord64;
672 void CheckValueInputRepresentationIs(Node
const* node,
int index,
673 MachineRepresentation representation) {
674 Node
const* input = node->InputAt(index);
675 MachineRepresentation input_representation =
676 inferrer_->GetRepresentation(input);
677 if (input_representation != representation) {
678 std::stringstream str;
679 str <<
"TypeError: node #" << node->id() <<
":" << *node->op()
680 <<
" uses node #" << input->id() <<
":" << *input->op() <<
":" 681 << input_representation <<
" which doesn't have a " << representation
682 <<
" representation.";
683 PrintDebugHelp(str, node);
684 FATAL(
"%s", str.str().c_str());
688 void CheckValueInputIsTagged(Node
const* node,
int index) {
689 Node
const* input = node->InputAt(index);
690 switch (inferrer_->GetRepresentation(input)) {
691 case MachineRepresentation::kTagged:
692 case MachineRepresentation::kTaggedPointer:
693 case MachineRepresentation::kTaggedSigned:
698 std::ostringstream str;
699 str <<
"TypeError: node #" << node->id() <<
":" << *node->op()
700 <<
" uses node #" << input->id() <<
":" << *input->op()
701 <<
" which doesn't have a tagged representation.";
702 PrintDebugHelp(str, node);
703 FATAL(
"%s", str.str().c_str());
706 void CheckValueInputIsTaggedOrPointer(Node
const* node,
int index) {
707 Node
const* input = node->InputAt(index);
708 switch (inferrer_->GetRepresentation(input)) {
709 case MachineRepresentation::kTagged:
710 case MachineRepresentation::kTaggedPointer:
711 case MachineRepresentation::kTaggedSigned:
713 case MachineRepresentation::kBit:
714 case MachineRepresentation::kWord8:
715 case MachineRepresentation::kWord16:
716 case MachineRepresentation::kWord32:
721 case MachineRepresentation::kWord64:
729 if (inferrer_->GetRepresentation(input) !=
730 MachineType::PointerRepresentation()) {
731 std::ostringstream str;
732 str <<
"TypeError: node #" << node->id() <<
":" << *node->op()
733 <<
" uses node #" << input->id() <<
":" << *input->op()
734 <<
" which doesn't have a tagged or pointer representation.";
735 PrintDebugHelp(str, node);
736 FATAL(
"%s", str.str().c_str());
740 void CheckValueInputForInt32Op(Node
const* node,
int index) {
741 Node
const* input = node->InputAt(index);
742 switch (inferrer_->GetRepresentation(input)) {
743 case MachineRepresentation::kBit:
744 case MachineRepresentation::kWord8:
745 case MachineRepresentation::kWord16:
746 case MachineRepresentation::kWord32:
748 case MachineRepresentation::kNone: {
749 std::ostringstream str;
750 str <<
"TypeError: node #" << input->id() <<
":" << *input->op()
752 PrintDebugHelp(str, node);
753 FATAL(
"%s", str.str().c_str());
759 std::ostringstream str;
760 str <<
"TypeError: node #" << node->id() <<
":" << *node->op()
761 <<
" uses node #" << input->id() <<
":" << *input->op()
762 <<
" which doesn't have an int32-compatible representation.";
763 PrintDebugHelp(str, node);
764 FATAL(
"%s", str.str().c_str());
767 void CheckValueInputForInt64Op(Node
const* node,
int index) {
768 Node
const* input = node->InputAt(index);
769 MachineRepresentation input_representation =
770 inferrer_->GetRepresentation(input);
771 switch (input_representation) {
772 case MachineRepresentation::kWord64:
774 case MachineRepresentation::kNone: {
775 std::ostringstream str;
776 str <<
"TypeError: node #" << input->id() <<
":" << *input->op()
778 PrintDebugHelp(str, node);
779 FATAL(
"%s", str.str().c_str());
786 std::ostringstream str;
787 str <<
"TypeError: node #" << node->id() <<
":" << *node->op()
788 <<
" uses node #" << input->id() <<
":" << *input->op() <<
":" 789 << input_representation
790 <<
" which doesn't have a kWord64 representation.";
791 PrintDebugHelp(str, node);
792 FATAL(
"%s", str.str().c_str());
795 void CheckValueInputForFloat32Op(Node
const* node,
int index) {
796 Node
const* input = node->InputAt(index);
797 if (MachineRepresentation::kFloat32 ==
798 inferrer_->GetRepresentation(input)) {
801 std::ostringstream str;
802 str <<
"TypeError: node #" << node->id() <<
":" << *node->op()
803 <<
" uses node #" << input->id() <<
":" << *input->op()
804 <<
" which doesn't have a kFloat32 representation.";
805 PrintDebugHelp(str, node);
806 FATAL(
"%s", str.str().c_str());
809 void CheckValueInputForFloat64Op(Node
const* node,
int index) {
810 Node
const* input = node->InputAt(index);
811 if (MachineRepresentation::kFloat64 ==
812 inferrer_->GetRepresentation(input)) {
815 std::ostringstream str;
816 str <<
"TypeError: node #" << node->id() <<
":" << *node->op()
817 <<
" uses node #" << input->id() <<
":" << *input->op()
818 <<
" which doesn't have a kFloat64 representation.";
819 PrintDebugHelp(str, node);
820 FATAL(
"%s", str.str().c_str());
823 void CheckCallInputs(Node
const* node) {
824 auto call_descriptor = CallDescriptorOf(node->op());
825 std::ostringstream str;
826 bool should_log_error =
false;
827 for (
size_t i = 0;
i < call_descriptor->InputCount(); ++
i) {
828 Node
const* input = node->InputAt(static_cast<int>(
i));
829 MachineRepresentation
const input_type =
830 inferrer_->GetRepresentation(input);
831 MachineRepresentation
const expected_input_type =
832 call_descriptor->GetInputType(
i).representation();
833 if (!IsCompatible(expected_input_type, input_type)) {
834 if (!should_log_error) {
835 should_log_error =
true;
836 str <<
"TypeError: node #" << node->id() <<
":" << *node->op()
837 <<
" has wrong type for:" << std::endl;
841 str <<
" * input " <<
i <<
" (" << input->id() <<
":" << *input->op()
842 <<
") has a " << input_type
843 <<
" representation (expected: " << expected_input_type <<
").";
846 if (should_log_error) {
847 PrintDebugHelp(str, node);
848 FATAL(
"%s", str.str().c_str());
852 bool Intersect(MachineRepresentation lhs, MachineRepresentation rhs) {
853 return (GetRepresentationProperties(lhs) &
854 GetRepresentationProperties(rhs)) != 0;
857 enum RepresentationProperties { kIsPointer = 1, kIsTagged = 2 };
859 int GetRepresentationProperties(MachineRepresentation representation) {
860 switch (representation) {
861 case MachineRepresentation::kTagged:
862 case MachineRepresentation::kTaggedPointer:
863 return kIsPointer | kIsTagged;
864 case MachineRepresentation::kTaggedSigned:
866 case MachineRepresentation::kWord32:
867 return MachineRepresentation::kWord32 ==
868 MachineType::PointerRepresentation()
871 case MachineRepresentation::kWord64:
872 return MachineRepresentation::kWord64 ==
873 MachineType::PointerRepresentation()
881 bool IsCompatible(MachineRepresentation expected,
882 MachineRepresentation actual) {
884 case MachineRepresentation::kTagged:
885 return (actual == MachineRepresentation::kTagged ||
886 actual == MachineRepresentation::kTaggedSigned ||
887 actual == MachineRepresentation::kTaggedPointer);
888 case MachineRepresentation::kTaggedSigned:
889 case MachineRepresentation::kTaggedPointer:
890 case MachineRepresentation::kFloat32:
891 case MachineRepresentation::kFloat64:
892 case MachineRepresentation::kSimd128:
893 case MachineRepresentation::kBit:
894 case MachineRepresentation::kWord8:
895 case MachineRepresentation::kWord16:
896 case MachineRepresentation::kWord64:
897 return expected == actual;
899 case MachineRepresentation::kWord32:
900 return (actual == MachineRepresentation::kBit ||
901 actual == MachineRepresentation::kWord8 ||
902 actual == MachineRepresentation::kWord16 ||
903 actual == MachineRepresentation::kWord32);
904 case MachineRepresentation::kNone:
910 void PrintDebugHelp(std::ostream& out, Node
const* node) {
912 out <<
"\n# Current block: " << *current_block_;
913 out <<
"\n#\n# Specify option --csa-trap-on-node=" << name_ <<
"," 914 << node->id() <<
" for debugging.";
918 Schedule
const*
const schedule_;
919 MachineRepresentationInferrer
const*
const inferrer_;
922 BasicBlock* current_block_;
927 void MachineGraphVerifier::Run(Graph* graph, Schedule
const*
const schedule,
928 Linkage* linkage,
bool is_stub,
const char* name,
930 MachineRepresentationInferrer representation_inferrer(schedule, graph,
932 MachineRepresentationChecker checker(schedule, &representation_inferrer,