v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
verifier.cc
Go to the documentation of this file.
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
6
7#include <algorithm>
8#include <deque>
9#include <queue>
10#include <sstream>
11#include <string>
12
17#include "src/compiler/node.h"
26
27namespace v8 {
28namespace internal {
29namespace compiler {
30
31
33 public:
39
40 void CheckSwitch(Node* node, const AllNodes& all);
41 void Check(Node* node, const AllNodes& all);
42
47
48 private:
49 void CheckNotTyped(Node* node) {
50 // Verification of simplified lowering sets types of many additional nodes.
51 if (v8_flags.verify_simplified_lowering) return;
52
53 if (NodeProperties::IsTyped(node)) {
54 std::ostringstream str;
55 str << "TypeError: node #" << node->id() << ":" << *node->op()
56 << " should never have a type";
57 FATAL("%s", str.str().c_str());
58 }
59 }
60 void CheckTypeIs(Node* node, Type type) {
61 if (typing == TYPED && !NodeProperties::GetType(node).Is(type)) {
62 std::ostringstream str;
63 str << "TypeError: node #" << node->id() << ":" << *node->op() << " type "
64 << NodeProperties::GetType(node) << " is not " << type;
65 FATAL("%s", str.str().c_str());
66 }
67 }
68 void CheckTypeMaybe(Node* node, Type type) {
69 if (typing == TYPED && !NodeProperties::GetType(node).Maybe(type)) {
70 std::ostringstream str;
71 str << "TypeError: node #" << node->id() << ":" << *node->op() << " type "
72 << NodeProperties::GetType(node) << " must intersect " << type;
73 FATAL("%s", str.str().c_str());
74 }
75 }
76 void CheckValueInputIs(Node* node, int i, Type type) {
77 Node* input = NodeProperties::GetValueInput(node, i);
78 if (typing == TYPED && !NodeProperties::GetType(input).Is(type)) {
79 std::ostringstream str;
80 str << "TypeError: node #" << node->id() << ":" << *node->op()
81 << "(input @" << i << " = " << input->opcode() << ":"
82 << input->op()->mnemonic() << ") type "
83 << NodeProperties::GetType(input) << " is not " << type;
84 FATAL("%s", str.str().c_str());
85 }
86 }
87 void CheckOutput(Node* node, Node* use, int count, const char* kind) {
88 if (count <= 0) {
89 std::ostringstream str;
90 str << "GraphError: node #" << node->id() << ":" << *node->op()
91 << " does not produce " << kind << " output used by node #"
92 << use->id() << ":" << *use->op();
93 FATAL("%s", str.str().c_str());
94 }
95 }
96};
97
99 // Count the number of {kIfValue} uses.
100 int case_count = 0;
101 bool expect_default = true;
102
103 // Data structure to check that each {kIfValue} has a unique value.
104 std::unordered_set<int32_t> if_value_parameters;
105
106 Node::Uses uses = node->uses();
107 for (const Node* use : uses) {
108 CHECK(all.IsLive(use));
109 switch (use->opcode()) {
110 case IrOpcode::kIfValue: {
111 // Check if each value is unique.
112 CHECK(
113 if_value_parameters.emplace(IfValueParametersOf(use->op()).value())
114 .second);
115 ++case_count;
116 break;
117 }
118 case IrOpcode::kIfDefault: {
119 // We expect exactly one {kIfDefault}.
120 CHECK(expect_default);
121 expect_default = false;
122 break;
123 }
124 default: {
125 FATAL("Switch #%d illegally used by #%d:%s", node->id(), use->id(),
126 use->op()->mnemonic());
127 }
128 }
129 }
130
131 CHECK(!expect_default);
132 // + 1 because of the one {kIfDefault}.
133 CHECK_EQ(node->op()->ControlOutputCount(), case_count + 1);
134 CheckNotTyped(node);
135}
136
137#ifdef DEBUG
138namespace {
139// Print more debug information just before a DCHECK failure.
140bool FailSoon(Node* node) {
141 v8::base::OS::PrintError("#\n# Verification failure for node:\n#\n");
142 node->Print(std::cerr);
143 return false;
144}
145} // namespace
146#endif // DEBUG
147
148void Verifier::Visitor::Check(Node* node, const AllNodes& all) {
149 int value_count = node->op()->ValueInputCount();
150 int context_count = OperatorProperties::GetContextInputCount(node->op());
151 int frame_state_count =
153 int effect_count = node->op()->EffectInputCount();
154 int control_count = node->op()->ControlInputCount();
155
156 // Verify number of inputs matches up.
157 int input_count = value_count + context_count + frame_state_count;
158 if (check_inputs == kAll) {
159 input_count += effect_count + control_count;
160 }
161 CHECK_EQ(input_count, node->InputCount());
162
163 // If this node has any effect outputs, make sure that it is
164 // consumed as an effect input somewhere else.
165 if (node->op()->EffectOutputCount() > 0) {
166#ifdef DEBUG
167 int effect_edges = 0;
168 for (Edge edge : node->use_edges()) {
169 if (all.IsLive(edge.from()) && NodeProperties::IsEffectEdge(edge)) {
170 effect_edges++;
171 }
172 }
173 if (effect_edges == 0) {
174 FailSoon(node);
175 }
176 DCHECK_GT(effect_edges, 0);
177#endif
178 }
179
180 // Verify that frame state has been inserted for the nodes that need it.
181 for (int i = 0; i < frame_state_count; i++) {
182 Node* frame_state = NodeProperties::GetFrameStateInput(node);
183 CHECK(frame_state->opcode() == IrOpcode::kFrameState ||
184 // kFrameState uses Start as a sentinel.
185 (node->opcode() == IrOpcode::kFrameState &&
186 frame_state->opcode() == IrOpcode::kStart));
187 }
188
189 // Verify all value inputs actually produce a value.
190 for (int i = 0; i < value_count; ++i) {
191 Node* value = NodeProperties::GetValueInput(node, i);
192 CheckOutput(value, node, value->op()->ValueOutputCount(), "value");
193 // Verify that only parameters and projections can have input nodes with
194 // multiple outputs.
195 CHECK(node->opcode() == IrOpcode::kParameter ||
196 node->opcode() == IrOpcode::kProjection ||
197 value->op()->ValueOutputCount() <= 1);
198 }
199
200 // Verify all context inputs are value nodes.
201 for (int i = 0; i < context_count; ++i) {
202 Node* context = NodeProperties::GetContextInput(node);
203 CheckOutput(context, node, context->op()->ValueOutputCount(), "context");
204 }
205
206 if (check_inputs == kAll) {
207 // Verify all effect inputs actually have an effect.
208 for (int i = 0; i < effect_count; ++i) {
209 Node* effect = NodeProperties::GetEffectInput(node);
210 CheckOutput(effect, node, effect->op()->EffectOutputCount(), "effect");
211 }
212
213 // Verify all control inputs are control nodes.
214 for (int i = 0; i < control_count; ++i) {
215 Node* control = NodeProperties::GetControlInput(node, i);
216 CheckOutput(control, node, control->op()->ControlOutputCount(),
217 "control");
218 }
219
220 // Verify that nodes that can throw either have both IfSuccess/IfException
221 // projections as the only control uses or no projections at all.
222 if (!node->op()->HasProperty(Operator::kNoThrow)) {
223 Node* discovered_if_exception = nullptr;
224 Node* discovered_if_success = nullptr;
225 Node* discovered_direct_use = nullptr;
226 int total_number_of_control_uses = 0;
227 for (Edge edge : node->use_edges()) {
229 continue;
230 }
231 total_number_of_control_uses++;
232 Node* control_use = edge.from();
233 if (control_use->opcode() == IrOpcode::kIfSuccess) {
234 CHECK_NULL(discovered_if_success); // Only one allowed.
235 discovered_if_success = control_use;
236 } else if (control_use->opcode() == IrOpcode::kIfException) {
237 CHECK_NULL(discovered_if_exception); // Only one allowed.
238 discovered_if_exception = control_use;
239 } else {
240 discovered_direct_use = control_use;
241 }
242 }
243 if (discovered_if_success && !discovered_if_exception) {
244 FATAL(
245 "#%d:%s should be followed by IfSuccess/IfException, but is "
246 "only followed by single #%d:%s",
247 node->id(), node->op()->mnemonic(), discovered_if_success->id(),
248 discovered_if_success->op()->mnemonic());
249 }
250 if (discovered_if_exception && !discovered_if_success) {
251 FATAL(
252 "#%d:%s should be followed by IfSuccess/IfException, but is "
253 "only followed by single #%d:%s",
254 node->id(), node->op()->mnemonic(), discovered_if_exception->id(),
255 discovered_if_exception->op()->mnemonic());
256 }
257 if ((discovered_if_success || discovered_if_exception) &&
258 total_number_of_control_uses != 2) {
259 FATAL(
260 "#%d:%s if followed by IfSuccess/IfException, there should be "
261 "no direct control uses, but direct use #%d:%s was found",
262 node->id(), node->op()->mnemonic(), discovered_direct_use->id(),
263 discovered_direct_use->op()->mnemonic());
264 }
265 }
266 }
267
268 switch (node->opcode()) {
269 case IrOpcode::kStart: {
270 // Start has no inputs.
271 CHECK_EQ(0, input_count);
272 // Type is a tuple.
273 // TODO(rossberg): Multiple outputs are currently typed as Internal.
274 CheckTypeIs(node, Type::Internal());
275 // Check that parameters are unique. We need this because the register
276 // allocator gets confused when there are two identical parameters which
277 // are both hard-assigned to the same register (such as the instance
278 // parameter in wasm).
279 std::unordered_set<int> param_indices;
280 for (Node* use : node->uses()) {
281 if (all.IsLive(use) && use->opcode() == IrOpcode::kParameter) {
282 int index = ParameterIndexOf(use->op());
283 CHECK_EQ(param_indices.count(index), 0);
284 param_indices.insert(index);
285 }
286 }
287 break;
288 }
289 case IrOpcode::kEnd:
290 // End has no outputs.
291 CHECK_EQ(0, node->op()->ValueOutputCount());
292 CHECK_EQ(0, node->op()->EffectOutputCount());
293 CHECK_EQ(0, node->op()->ControlOutputCount());
294 // All inputs are graph terminators.
295 for (const Node* input : node->inputs()) {
296 CHECK(IrOpcode::IsGraphTerminator(input->opcode()));
297 }
298 CheckNotTyped(node);
299 break;
300 case IrOpcode::kDead:
301 // Dead is never connected to the graph.
302 UNREACHABLE();
303 case IrOpcode::kDeadValue:
304 CheckValueInputIs(node, 0, Type::None());
305 CheckTypeIs(node, Type::None());
306 break;
307 case IrOpcode::kUnreachable:
308 CheckTypeIs(node, Type::None());
309 for (Edge edge : node->use_edges()) {
310 Node* use = edge.from();
311 if (NodeProperties::IsValueEdge(edge) && all.IsLive(use)) {
312 // {Unreachable} nodes can only be used by {DeadValue}, because they
313 // don't actually produce a value.
314 CHECK_EQ(IrOpcode::kDeadValue, use->opcode());
315 }
316 }
317 break;
318 case IrOpcode::kBranch: {
319 // Branch uses are IfTrue and IfFalse.
320 int count_true = 0, count_false = 0;
321 for (const Node* use : node->uses()) {
322 CHECK(all.IsLive(use) && (use->opcode() == IrOpcode::kIfTrue ||
323 use->opcode() == IrOpcode::kIfFalse));
324 if (use->opcode() == IrOpcode::kIfTrue) ++count_true;
325 if (use->opcode() == IrOpcode::kIfFalse) ++count_false;
326 }
327 CHECK_EQ(1, count_true);
328 CHECK_EQ(1, count_false);
329 switch (BranchParametersOf(node->op()).semantics()) {
332 // The condition must be a Boolean.
333 CheckValueInputIs(node, 0, Type::Boolean());
334 break;
336 CheckValueInputIs(node, 0, Type::Machine());
337 break;
338 }
339 CheckNotTyped(node);
340 break;
341 }
342 case IrOpcode::kIfTrue:
343 case IrOpcode::kIfFalse: {
344 Node* control = NodeProperties::GetControlInput(node, 0);
345 CHECK_EQ(IrOpcode::kBranch, control->opcode());
346 CheckNotTyped(node);
347 break;
348 }
349 case IrOpcode::kIfSuccess: {
350 // IfSuccess and IfException continuation only on throwing nodes.
351 Node* input = NodeProperties::GetControlInput(node, 0);
352 CHECK(!input->op()->HasProperty(Operator::kNoThrow));
353 CheckNotTyped(node);
354 break;
355 }
356 case IrOpcode::kIfException: {
357 // IfSuccess and IfException continuation only on throwing nodes.
358 Node* input = NodeProperties::GetControlInput(node, 0);
359 CHECK(!input->op()->HasProperty(Operator::kNoThrow));
360 CheckTypeIs(node, Type::Any());
361 break;
362 }
363 case IrOpcode::kSwitch: {
364 CheckSwitch(node, all);
365 break;
366 }
367 case IrOpcode::kIfValue:
368 case IrOpcode::kIfDefault:
369 CHECK_EQ(IrOpcode::kSwitch,
370 NodeProperties::GetControlInput(node)->opcode());
371 CheckNotTyped(node);
372 break;
373 case IrOpcode::kLoop: {
374 CHECK_EQ(control_count, input_count);
375 CheckNotTyped(node);
376 // All loops need to be connected to a {Terminate} node to ensure they
377 // stay connected to the graph end.
378 bool has_terminate = false;
379 for (const Node* use : node->uses()) {
380 if (all.IsLive(use) && use->opcode() == IrOpcode::kTerminate) {
381 has_terminate = true;
382 break;
383 }
384 }
385 CHECK(has_terminate);
386 break;
387 }
388 case IrOpcode::kMerge:
389 CHECK_EQ(control_count, input_count);
390 CheckNotTyped(node);
391 break;
392 case IrOpcode::kDeoptimizeIf:
393 case IrOpcode::kDeoptimizeUnless:
394 case IrOpcode::kPlug:
395 case IrOpcode::kTrapIf:
396 case IrOpcode::kTrapUnless:
397 case IrOpcode::kAssert:
398 CheckNotTyped(node);
399 break;
400 case IrOpcode::kDeoptimize:
401 case IrOpcode::kReturn:
402 case IrOpcode::kThrow:
403 // Deoptimize, Return and Throw uses are End.
404 for (const Node* use : node->uses()) {
405 if (all.IsLive(use)) {
406 CHECK_EQ(IrOpcode::kEnd, use->opcode());
407 }
408 }
409 CheckNotTyped(node);
410 break;
411 case IrOpcode::kTerminate:
412 // Terminates take one loop and effect.
413 CHECK_EQ(1, control_count);
414 CHECK_EQ(1, effect_count);
415 CHECK_EQ(2, input_count);
416 CHECK_EQ(IrOpcode::kLoop,
417 NodeProperties::GetControlInput(node)->opcode());
418 // Terminate uses are End.
419 for (const Node* use : node->uses()) {
420 if (all.IsLive(use)) {
421 CHECK_EQ(IrOpcode::kEnd, use->opcode());
422 }
423 }
424 CheckNotTyped(node);
425 break;
426
427 // Common operators
428 // ----------------
429 case IrOpcode::kParameter: {
430 // Parameters have the start node as inputs.
431 CHECK_EQ(1, input_count);
432 // Parameter has an input that produces enough values.
433 int const index = ParameterIndexOf(node->op());
435 // Currently, parameter indices start at -1 instead of 0.
436 CHECK_LE(-1, index);
437 CHECK_LE(index, start.LastParameterIndex_MaybeNonStandardLayout());
438 CheckTypeIs(node, Type::Any());
439 break;
440 }
441 case IrOpcode::kInt32Constant: // TODO(turbofan): rename Word32Constant?
442 case IrOpcode::kInt64Constant: { // TODO(turbofan): rename Word64Constant?
443 // Constants have no inputs.
444 CHECK_EQ(0, input_count);
445 // Wasm numeric constants have types. However, since wasm only gets
446 // verified in untyped mode, we do not need to check that the types match.
447 // TODO(manoskouk): Verify the type if wasm runs in typed mode.
448 if (code_type != kWasm) CheckTypeIs(node, Type::Machine());
449 break;
450 }
451 case IrOpcode::kFloat32Constant:
452 case IrOpcode::kFloat64Constant: {
453 // Constants have no inputs.
454 CHECK_EQ(0, input_count);
455 // Wasm numeric constants have types. However, since wasm only gets
456 // verified in untyped mode, we do not need to check that the types match.
457 // TODO(manoskouk): Verify the type if wasm runs in typed mode.
458 if (code_type != kWasm) CheckNotTyped(node);
459 break;
460 }
461 case IrOpcode::kTaggedIndexConstant:
462 case IrOpcode::kRelocatableInt32Constant:
463 case IrOpcode::kRelocatableInt64Constant:
464 // Constants have no inputs.
465 CHECK_EQ(0, input_count);
466 CheckNotTyped(node);
467 break;
468 case IrOpcode::kNumberConstant:
469 // Constants have no inputs.
470 CHECK_EQ(0, input_count);
471 CheckTypeIs(node, Type::Number());
472 break;
473 case IrOpcode::kHeapConstant:
474 case IrOpcode::kCompressedHeapConstant:
475 case IrOpcode::kTrustedHeapConstant:
476 // Constants have no inputs.
477 CHECK_EQ(0, input_count);
478 CheckTypeIs(node, Type::Any());
479 break;
480 case IrOpcode::kExternalConstant:
481 case IrOpcode::kPointerConstant:
482 // Constants have no inputs.
483 CHECK_EQ(0, input_count);
484 CheckTypeIs(node, Type::ExternalPointer());
485 break;
486 case IrOpcode::kOsrValue:
487 // OSR values have a value and a control input.
488 CHECK_EQ(1, control_count);
489 CHECK_EQ(1, input_count);
490 // Type is merged from other values in the graph and could be any.
491 CheckTypeIs(node, Type::Any());
492 break;
493 case IrOpcode::kProjection: {
494 // Projection has an input that produces enough values.
495 int index = static_cast<int>(ProjectionIndexOf(node->op()));
496 Node* input = NodeProperties::GetValueInput(node, 0);
497 CHECK_GT(input->op()->ValueOutputCount(), index);
498 CheckTypeIs(node, Type::Any());
499 break;
500 }
501 case IrOpcode::kSelect: {
502 CHECK_EQ(0, effect_count);
503 CHECK_EQ(0, control_count);
504 CHECK_EQ(3, value_count);
505 switch (SelectParametersOf(node->op()).semantics()) {
508 // The condition must be a Boolean.
509 CheckValueInputIs(node, 0, Type::Boolean());
510 break;
512 CheckValueInputIs(node, 0, Type::Machine());
513 break;
514 }
515 CheckTypeIs(node, Type::Any());
516 break;
517 }
518 case IrOpcode::kPhi: {
519 // Phi input count matches parent control node.
520 CHECK_EQ(0, effect_count);
521 CHECK_EQ(1, control_count);
522 Node* control = NodeProperties::GetControlInput(node, 0);
523 CHECK_EQ(value_count, control->op()->ControlInputCount());
524 CHECK_EQ(input_count, 1 + value_count);
525 // Type must be subsumed by all input types.
526 // TODO(rossberg): for now at least, narrowing does not really hold.
527 /*
528 for (int i = 0; i < value_count; ++i) {
529 CHECK(type_of(ValueInput(node, i))->Is(type_of(node)));
530 }
531 */
532 break;
533 }
534 case IrOpcode::kInductionVariablePhi: {
535 // This is only a temporary node for the typer.
536 UNREACHABLE();
537 }
538 case IrOpcode::kEffectPhi: {
539 // EffectPhi input count matches parent control node.
540 CHECK_EQ(0, value_count);
541 CHECK_EQ(1, control_count);
542 Node* control = NodeProperties::GetControlInput(node, 0);
543 CHECK_EQ(effect_count, control->op()->ControlInputCount());
544 CHECK_EQ(input_count, 1 + effect_count);
545 // If the control input is a Merge, then make sure that at least one of
546 // its usages is non-phi.
547 if (control->opcode() == IrOpcode::kMerge) {
548 bool non_phi_use_found = false;
549 for (Node* use : control->uses()) {
550 if (all.IsLive(use) && use->opcode() != IrOpcode::kEffectPhi &&
551 use->opcode() != IrOpcode::kPhi) {
552 non_phi_use_found = true;
553 }
554 }
555 CHECK(non_phi_use_found);
556 }
557 break;
558 }
559 case IrOpcode::kLoopExit: {
560 CHECK_EQ(2, control_count);
561 Node* loop = NodeProperties::GetControlInput(node, 1);
562 CHECK_EQ(IrOpcode::kLoop, loop->opcode());
563 break;
564 }
565 case IrOpcode::kLoopExitValue: {
566 CHECK_EQ(1, control_count);
567 Node* loop_exit = NodeProperties::GetControlInput(node, 0);
568 CHECK_EQ(IrOpcode::kLoopExit, loop_exit->opcode());
569 break;
570 }
571 case IrOpcode::kLoopExitEffect: {
572 CHECK_EQ(1, control_count);
573 Node* loop_exit = NodeProperties::GetControlInput(node, 0);
574 CHECK_EQ(IrOpcode::kLoopExit, loop_exit->opcode());
575 break;
576 }
577 case IrOpcode::kCheckpoint:
578 CheckNotTyped(node);
579 break;
580 case IrOpcode::kBeginRegion:
581 // TODO(rossberg): what are the constraints on these?
582 break;
583 case IrOpcode::kFinishRegion: {
584 // TODO(rossberg): what are the constraints on these?
585 // Type must be subsumed by input type.
586 if (typing == TYPED) {
587 Node* val = NodeProperties::GetValueInput(node, 0);
589 }
590 break;
591 }
592 case IrOpcode::kFrameState: {
593 // TODO(jarin): what are the constraints on these?
594 CHECK_EQ(5, value_count);
595 CHECK_EQ(0, control_count);
596 CHECK_EQ(0, effect_count);
597 CHECK_EQ(6, input_count);
598
599 FrameState state{node};
600 CHECK(state.parameters()->opcode() == IrOpcode::kStateValues ||
601 state.parameters()->opcode() == IrOpcode::kTypedStateValues);
602 CHECK(state.locals()->opcode() == IrOpcode::kStateValues ||
603 state.locals()->opcode() == IrOpcode::kTypedStateValues);
604
605 // Checks that the state input is empty for all but kInterpretedFunction
606 // frames, where it should have size one.
607 {
608 const FrameStateFunctionInfo* func_info =
609 state.frame_state_info().function_info();
610 CHECK_EQ(func_info->parameter_count(),
611 StateValuesAccess(state.parameters()).size());
612 CHECK_EQ(func_info->local_count(),
613 StateValuesAccess(state.locals()).size());
614
615 Node* accumulator = state.stack();
616 if (func_info->type() == FrameStateType::kUnoptimizedFunction) {
617 // The accumulator (InputAt(2)) cannot be kStateValues.
618 // It can be kTypedStateValues (to signal the type) and it can have
619 // other Node types including that of the optimized_out HeapConstant.
620 CHECK_NE(accumulator->opcode(), IrOpcode::kStateValues);
621 if (accumulator->opcode() == IrOpcode::kTypedStateValues) {
622 CHECK_EQ(1, StateValuesAccess(accumulator).size());
623 }
624 } else {
625 CHECK(accumulator->opcode() == IrOpcode::kTypedStateValues ||
626 accumulator->opcode() == IrOpcode::kStateValues);
627 CHECK_EQ(0, StateValuesAccess(accumulator).size());
628 }
629 }
630 break;
631 }
632 case IrOpcode::kObjectId:
633 CheckTypeIs(node, Type::Object());
634 break;
635 case IrOpcode::kStateValues:
636 case IrOpcode::kTypedStateValues:
637 case IrOpcode::kArgumentsElementsState:
638 case IrOpcode::kArgumentsLengthState:
639 case IrOpcode::kObjectState:
640 case IrOpcode::kTypedObjectState:
641 // TODO(jarin): what are the constraints on these?
642 break;
643 case IrOpcode::kCall:
644 // TODO(rossberg): what are the constraints on these?
645 break;
646 case IrOpcode::kTailCall:
647 // TODO(bmeurer): what are the constraints on these?
648 break;
649 case IrOpcode::kEnterMachineGraph:
650 CheckTypeIs(node, Type::Machine());
651 break;
652 case IrOpcode::kExitMachineGraph:
653 CheckValueInputIs(node, 0, Type::Machine());
654 break;
655
656 // JavaScript operators
657 // --------------------
658 case IrOpcode::kJSEqual:
659 case IrOpcode::kJSStrictEqual:
660 case IrOpcode::kJSLessThan:
661 case IrOpcode::kJSGreaterThan:
662 case IrOpcode::kJSLessThanOrEqual:
663 case IrOpcode::kJSGreaterThanOrEqual:
664 CheckTypeIs(node, Type::Boolean());
665 break;
666
667 case IrOpcode::kJSAdd:
668 CheckTypeIs(node, Type::NumericOrString());
669 break;
670 case IrOpcode::kJSBitwiseOr:
671 case IrOpcode::kJSBitwiseXor:
672 case IrOpcode::kJSBitwiseAnd:
673 case IrOpcode::kJSShiftLeft:
674 case IrOpcode::kJSShiftRight:
675 case IrOpcode::kJSShiftRightLogical:
676 case IrOpcode::kJSSubtract:
677 case IrOpcode::kJSMultiply:
678 case IrOpcode::kJSDivide:
679 case IrOpcode::kJSModulus:
680 case IrOpcode::kJSExponentiate:
681 case IrOpcode::kJSBitwiseNot:
682 case IrOpcode::kJSDecrement:
683 case IrOpcode::kJSIncrement:
684 case IrOpcode::kJSNegate:
685 CheckTypeIs(node, Type::Numeric());
686 break;
687
688 case IrOpcode::kToBoolean:
689 CheckTypeIs(node, Type::Boolean());
690 break;
691 case IrOpcode::kJSToLength:
692 CheckTypeIs(node, Type::Range(0, kMaxSafeInteger, zone));
693 break;
694 case IrOpcode::kJSToName:
695 CheckTypeIs(node, Type::Name());
696 break;
697 case IrOpcode::kJSToNumber:
698 case IrOpcode::kJSToNumberConvertBigInt:
699 CheckTypeIs(node, Type::Number());
700 break;
701 case IrOpcode::kJSToBigInt:
702 case IrOpcode::kJSToBigIntConvertNumber:
703 CheckTypeIs(node, Type::BigInt());
704 break;
705 case IrOpcode::kJSToNumeric:
706 CheckTypeIs(node, Type::Numeric());
707 break;
708 case IrOpcode::kJSToString:
709 CheckTypeIs(node, Type::String());
710 break;
711 case IrOpcode::kJSToObject:
712 CheckTypeIs(node, Type::Receiver());
713 break;
714 case IrOpcode::kJSParseInt:
715 CheckValueInputIs(node, 0, Type::Any());
716 CheckValueInputIs(node, 1, Type::Any());
717 CheckTypeIs(node, Type::Number());
718 break;
719 case IrOpcode::kJSRegExpTest:
720 CheckValueInputIs(node, 0, Type::Any());
721 CheckValueInputIs(node, 1, Type::String());
722 CheckTypeIs(node, Type::Boolean());
723 break;
724 case IrOpcode::kJSCreate:
725 CheckTypeIs(node, Type::Object());
726 break;
727 case IrOpcode::kJSCreateArguments:
728 CheckTypeIs(node, Type::ArrayOrOtherObject());
729 break;
730 case IrOpcode::kJSCreateArray:
731 CheckTypeIs(node, Type::Array());
732 break;
733 case IrOpcode::kJSCreateArrayIterator:
734 CheckTypeIs(node, Type::OtherObject());
735 break;
736 case IrOpcode::kJSCreateAsyncFunctionObject:
737 CheckTypeIs(node, Type::OtherObject());
738 break;
739 case IrOpcode::kJSCreateCollectionIterator:
740 CheckTypeIs(node, Type::OtherObject());
741 break;
742 case IrOpcode::kJSCreateBoundFunction:
743 CheckTypeIs(node, Type::BoundFunction());
744 break;
745 case IrOpcode::kJSCreateClosure:
746 CheckTypeIs(node, Type::Function());
747 break;
748 case IrOpcode::kJSCreateIterResultObject:
749 CheckTypeIs(node, Type::OtherObject());
750 break;
751 case IrOpcode::kJSCreateStringIterator:
752 CheckTypeIs(node, Type::OtherObject());
753 break;
754 case IrOpcode::kJSCreateKeyValueArray:
755 CheckTypeIs(node, Type::Array());
756 break;
757 case IrOpcode::kJSCreateObject:
758 CheckTypeIs(node, Type::OtherObject());
759 break;
760 case IrOpcode::kJSCreateStringWrapper:
761 CheckTypeIs(node, Type::StringWrapper());
762 break;
763 case IrOpcode::kJSCreatePromise:
764 CheckTypeIs(node, Type::OtherObject());
765 break;
766 case IrOpcode::kJSCreateTypedArray:
767 CheckTypeIs(node, Type::TypedArray());
768 break;
769 case IrOpcode::kJSCreateLiteralArray:
770 CheckTypeIs(node, Type::Array());
771 break;
772 case IrOpcode::kJSCreateEmptyLiteralArray:
773 CheckTypeIs(node, Type::Array());
774 break;
775 case IrOpcode::kJSCreateArrayFromIterable:
776 CheckTypeIs(node, Type::Array());
777 break;
778 case IrOpcode::kJSCreateLiteralObject:
779 case IrOpcode::kJSCreateEmptyLiteralObject:
780 case IrOpcode::kJSCloneObject:
781 case IrOpcode::kJSCreateLiteralRegExp:
782 CheckTypeIs(node, Type::OtherObject());
783 break;
784 case IrOpcode::kJSGetTemplateObject:
785 CheckTypeIs(node, Type::Array());
786 break;
787 case IrOpcode::kJSLoadProperty:
788 CheckTypeIs(node, Type::Any());
789 CHECK(PropertyAccessOf(node->op()).feedback().IsValid());
790 break;
791 case IrOpcode::kJSLoadNamed:
792 CheckTypeIs(node, Type::Any());
793 break;
794 case IrOpcode::kJSLoadNamedFromSuper:
795 CheckTypeIs(node, Type::Any());
796 break;
797 case IrOpcode::kJSLoadGlobal:
798 CheckTypeIs(node, Type::Any());
799 CHECK(LoadGlobalParametersOf(node->op()).feedback().IsValid());
800 break;
801 case IrOpcode::kJSSetKeyedProperty:
802 CheckNotTyped(node);
803 CHECK(PropertyAccessOf(node->op()).feedback().IsValid());
804 break;
805 case IrOpcode::kJSDefineKeyedOwnProperty:
806 CheckNotTyped(node);
807 CHECK(PropertyAccessOf(node->op()).feedback().IsValid());
808 break;
809 case IrOpcode::kJSSetNamedProperty:
810 CheckNotTyped(node);
811 break;
812 case IrOpcode::kJSStoreGlobal:
813 CheckNotTyped(node);
814 CHECK(StoreGlobalParametersOf(node->op()).feedback().IsValid());
815 break;
816 case IrOpcode::kJSDefineNamedOwnProperty:
817 CheckNotTyped(node);
818 CHECK(
820 break;
821 case IrOpcode::kJSGetIterator:
822 CheckValueInputIs(node, 0, Type::Any());
823 CheckTypeIs(node, Type::Any());
824 break;
825 case IrOpcode::kJSDefineKeyedOwnPropertyInLiteral:
826 case IrOpcode::kJSStoreInArrayLiteral:
827 CheckNotTyped(node);
828 CHECK(FeedbackParameterOf(node->op()).feedback().IsValid());
829 break;
830 case IrOpcode::kJSDeleteProperty:
831 case IrOpcode::kJSHasProperty:
832 case IrOpcode::kJSHasInPrototypeChain:
833 case IrOpcode::kJSInstanceOf:
834 case IrOpcode::kJSOrdinaryHasInstance:
835 CheckTypeIs(node, Type::Boolean());
836 break;
837 case IrOpcode::kTypeOf:
838 CheckTypeIs(node, Type::InternalizedString());
839 break;
840 case IrOpcode::kJSGetSuperConstructor:
841 // We don't check the input for Type::Function because this_function can
842 // be context-allocated.
843 CheckValueInputIs(node, 0, Type::Any());
844 CheckTypeIs(node, Type::NonInternal());
845 break;
846 case IrOpcode::kJSFindNonDefaultConstructorOrConstruct:
847 CheckValueInputIs(node, 0, Type::Any());
848 CheckValueInputIs(node, 1, Type::Any());
849 break;
850 case IrOpcode::kJSHasContextExtension:
851 CheckTypeIs(node, Type::Boolean());
852 break;
853 case IrOpcode::kJSLoadContext:
854 case IrOpcode::kJSLoadScriptContext:
855 CheckTypeIs(node, Type::Any());
856 break;
857 case IrOpcode::kJSStoreContext:
858 case IrOpcode::kJSStoreScriptContext:
859 CheckNotTyped(node);
860 break;
861 case IrOpcode::kJSCreateFunctionContext:
862 case IrOpcode::kJSCreateCatchContext:
863 case IrOpcode::kJSCreateWithContext:
864 case IrOpcode::kJSCreateBlockContext: {
865 CheckTypeIs(node, Type::OtherInternal());
866 break;
867 }
868
869 case IrOpcode::kJSConstructForwardVarargs:
870 case IrOpcode::kJSConstructForwardAllArgs:
871 case IrOpcode::kJSConstruct:
872 case IrOpcode::kJSConstructWithArrayLike:
873 case IrOpcode::kJSConstructWithSpread:
874 CheckTypeIs(node, Type::Receiver());
875 break;
876 case IrOpcode::kJSCallForwardVarargs:
877 case IrOpcode::kJSCall:
878 case IrOpcode::kJSCallWithArrayLike:
879 case IrOpcode::kJSCallWithSpread:
880 case IrOpcode::kJSCallRuntime:
881 CheckTypeIs(node, Type::Any());
882 break;
883
884 case IrOpcode::kJSForInEnumerate:
885 CheckValueInputIs(node, 0, Type::Any());
886 CheckTypeIs(node, Type::OtherInternal());
887 break;
888 case IrOpcode::kJSForInPrepare:
889 CheckTypeIs(node, Type::Any());
890 break;
891 case IrOpcode::kJSForInNext:
892 CheckTypeIs(node, Type::Union(Type::Name(), Type::Undefined(), zone));
893 break;
894
895 case IrOpcode::kJSLoadMessage:
896 case IrOpcode::kJSStoreMessage:
897 break;
898
899 case IrOpcode::kJSLoadModule:
900 CheckTypeIs(node, Type::Any());
901 break;
902 case IrOpcode::kJSStoreModule:
903 CheckNotTyped(node);
904 break;
905
906 case IrOpcode::kJSGetImportMeta:
907 CheckTypeIs(node, Type::Any());
908 break;
909
910 case IrOpcode::kJSGeneratorStore:
911 CheckNotTyped(node);
912 break;
913
914 case IrOpcode::kJSCreateGeneratorObject:
915 CheckTypeIs(node, Type::OtherObject());
916 break;
917
918 case IrOpcode::kJSGeneratorRestoreContinuation:
919 CheckTypeIs(node, Type::SignedSmall());
920 break;
921
922 case IrOpcode::kJSGeneratorRestoreContext:
923 CheckTypeIs(node, Type::Any());
924 break;
925
926 case IrOpcode::kJSGeneratorRestoreRegister:
927 CheckTypeIs(node, Type::Any());
928 break;
929
930 case IrOpcode::kJSGeneratorRestoreInputOrDebugPos:
931 CheckTypeIs(node, Type::Any());
932 break;
933
934 case IrOpcode::kJSStackCheck:
935 case IrOpcode::kJSDebugger:
936 CheckNotTyped(node);
937 break;
938
939 case IrOpcode::kJSAsyncFunctionEnter:
940 CheckValueInputIs(node, 0, Type::Any());
941 CheckValueInputIs(node, 1, Type::Any());
942 CheckTypeIs(node, Type::OtherObject());
943 break;
944 case IrOpcode::kJSAsyncFunctionReject:
945 CheckValueInputIs(node, 0, Type::Any());
946 CheckValueInputIs(node, 1, Type::Any());
947 CheckTypeIs(node, Type::OtherObject());
948 break;
949 case IrOpcode::kJSAsyncFunctionResolve:
950 CheckValueInputIs(node, 0, Type::Any());
951 CheckValueInputIs(node, 1, Type::Any());
952 CheckTypeIs(node, Type::OtherObject());
953 break;
954 case IrOpcode::kJSFulfillPromise:
955 CheckValueInputIs(node, 0, Type::Any());
956 CheckValueInputIs(node, 1, Type::Any());
957 CheckTypeIs(node, Type::Undefined());
958 break;
959 case IrOpcode::kJSPerformPromiseThen:
960 CheckValueInputIs(node, 0, Type::Any());
961 CheckValueInputIs(node, 1, Type::Any());
962 CheckValueInputIs(node, 2, Type::Any());
963 CheckValueInputIs(node, 3, Type::Any());
964 CheckTypeIs(node, Type::Receiver());
965 break;
966 case IrOpcode::kJSPromiseResolve:
967 CheckValueInputIs(node, 0, Type::Any());
968 CheckValueInputIs(node, 1, Type::Any());
969 CheckTypeIs(node, Type::Receiver());
970 break;
971 case IrOpcode::kJSRejectPromise:
972 CheckValueInputIs(node, 0, Type::Any());
973 CheckValueInputIs(node, 1, Type::Any());
974 CheckValueInputIs(node, 2, Type::Any());
975 CheckTypeIs(node, Type::Undefined());
976 break;
977 case IrOpcode::kJSResolvePromise:
978 CheckValueInputIs(node, 0, Type::Any());
979 CheckValueInputIs(node, 1, Type::Any());
980 CheckTypeIs(node, Type::Undefined());
981 break;
982 case IrOpcode::kJSObjectIsArray:
983 CheckValueInputIs(node, 0, Type::Any());
984 CheckTypeIs(node, Type::Boolean());
985 break;
986
987 case IrOpcode::kComment:
988 case IrOpcode::kAbortCSADcheck:
989 case IrOpcode::kDebugBreak:
990 case IrOpcode::kRetain:
991 case IrOpcode::kRuntimeAbort:
992 CheckNotTyped(node);
993 break;
994
995 // Simplified operators
996 // -------------------------------
997 case IrOpcode::kBooleanNot:
998 CheckValueInputIs(node, 0, Type::Boolean());
999 CheckTypeIs(node, Type::Boolean());
1000 break;
1001 case IrOpcode::kNumberEqual:
1002 CheckValueInputIs(node, 0, Type::Number());
1003 CheckValueInputIs(node, 1, Type::Number());
1004 CheckTypeIs(node, Type::Boolean());
1005 break;
1006 case IrOpcode::kNumberLessThan:
1007 case IrOpcode::kNumberLessThanOrEqual:
1008 CheckValueInputIs(node, 0, Type::Number());
1009 CheckValueInputIs(node, 1, Type::Number());
1010 CheckTypeIs(node, Type::Boolean());
1011 break;
1012 case IrOpcode::kSpeculativeAdditiveSafeIntegerAdd:
1013 case IrOpcode::kSpeculativeAdditiveSafeIntegerSubtract:
1014 case IrOpcode::kSpeculativeSmallIntegerAdd:
1015 case IrOpcode::kSpeculativeSmallIntegerSubtract:
1016 case IrOpcode::kSpeculativeNumberAdd:
1017 case IrOpcode::kSpeculativeNumberSubtract:
1018 case IrOpcode::kSpeculativeNumberMultiply:
1019 case IrOpcode::kSpeculativeNumberPow:
1020 case IrOpcode::kSpeculativeNumberDivide:
1021 case IrOpcode::kSpeculativeNumberModulus:
1022 CheckTypeIs(node, Type::Number());
1023 break;
1024 case IrOpcode::kSpeculativeNumberEqual:
1025 case IrOpcode::kSpeculativeNumberLessThan:
1026 case IrOpcode::kSpeculativeNumberLessThanOrEqual:
1027 CheckTypeIs(node, Type::Boolean());
1028 break;
1029#define SPECULATIVE_BIGINT_BINOP(Name) case IrOpcode::k##Name:
1031#undef SPECULATIVE_BIGINT_BINOP
1032 CheckTypeIs(node, Type::BigInt());
1033 break;
1034 case IrOpcode::kSpeculativeBigIntEqual:
1035 case IrOpcode::kSpeculativeBigIntLessThan:
1036 case IrOpcode::kSpeculativeBigIntLessThanOrEqual:
1037 CheckTypeIs(node, Type::Boolean());
1038 break;
1039 case IrOpcode::kSpeculativeBigIntNegate:
1040 CheckTypeIs(node, Type::BigInt());
1041 break;
1042 case IrOpcode::kSpeculativeBigIntAsIntN:
1043 case IrOpcode::kSpeculativeBigIntAsUintN:
1044 CheckValueInputIs(node, 0, Type::Any());
1045 CheckTypeIs(node, Type::BigInt());
1046 break;
1047#define BIGINT_BINOP(Name) case IrOpcode::k##Name:
1049#undef BIGINT_BINOP
1050 CheckValueInputIs(node, 0, Type::BigInt());
1051 CheckValueInputIs(node, 1, Type::BigInt());
1052 CheckTypeIs(node, Type::BigInt());
1053 break;
1054 case IrOpcode::kBigIntEqual:
1055 case IrOpcode::kBigIntLessThan:
1056 case IrOpcode::kBigIntLessThanOrEqual:
1057 CheckValueInputIs(node, 0, Type::BigInt());
1058 CheckValueInputIs(node, 1, Type::BigInt());
1059 CheckTypeIs(node, Type::Boolean());
1060 break;
1061 case IrOpcode::kBigIntNegate:
1062 CheckValueInputIs(node, 0, Type::BigInt());
1063 CheckTypeIs(node, Type::BigInt());
1064 break;
1065 case IrOpcode::kSpeculativeToBigInt:
1066 CheckValueInputIs(node, 0, Type::Any());
1067 CheckTypeIs(node, Type::BigInt());
1068 break;
1069 case IrOpcode::kNumberAdd:
1070 case IrOpcode::kNumberSubtract:
1071 case IrOpcode::kNumberMultiply:
1072 case IrOpcode::kNumberDivide:
1073 CheckValueInputIs(node, 0, Type::Number());
1074 CheckValueInputIs(node, 1, Type::Number());
1075 CheckTypeIs(node, Type::Number());
1076 break;
1077 case IrOpcode::kNumberModulus:
1078 CheckValueInputIs(node, 0, Type::Number());
1079 CheckValueInputIs(node, 1, Type::Number());
1080 CheckTypeIs(node, Type::Number());
1081 break;
1082 case IrOpcode::kNumberBitwiseOr:
1083 case IrOpcode::kNumberBitwiseXor:
1084 case IrOpcode::kNumberBitwiseAnd:
1085 CheckValueInputIs(node, 0, Type::Signed32());
1086 CheckValueInputIs(node, 1, Type::Signed32());
1087 CheckTypeIs(node, Type::Signed32());
1088 break;
1089 case IrOpcode::kSpeculativeNumberBitwiseOr:
1090 case IrOpcode::kSpeculativeNumberBitwiseXor:
1091 case IrOpcode::kSpeculativeNumberBitwiseAnd:
1092 CheckTypeIs(node, Type::Signed32());
1093 break;
1094 case IrOpcode::kNumberShiftLeft:
1095 case IrOpcode::kNumberShiftRight:
1096 CheckValueInputIs(node, 0, Type::Signed32());
1097 CheckValueInputIs(node, 1, Type::Unsigned32());
1098 CheckTypeIs(node, Type::Signed32());
1099 break;
1100 case IrOpcode::kSpeculativeNumberShiftLeft:
1101 case IrOpcode::kSpeculativeNumberShiftRight:
1102 CheckTypeIs(node, Type::Signed32());
1103 break;
1104 case IrOpcode::kNumberShiftRightLogical:
1105 CheckValueInputIs(node, 0, Type::Unsigned32());
1106 CheckValueInputIs(node, 1, Type::Unsigned32());
1107 CheckTypeIs(node, Type::Unsigned32());
1108 break;
1109 case IrOpcode::kSpeculativeNumberShiftRightLogical:
1110 CheckTypeIs(node, Type::Unsigned32());
1111 break;
1112 case IrOpcode::kNumberImul:
1113 CheckValueInputIs(node, 0, Type::Unsigned32());
1114 CheckValueInputIs(node, 1, Type::Unsigned32());
1115 CheckTypeIs(node, Type::Signed32());
1116 break;
1117 case IrOpcode::kNumberClz32:
1118 CheckValueInputIs(node, 0, Type::Unsigned32());
1119 CheckTypeIs(node, Type::Unsigned32());
1120 break;
1121 case IrOpcode::kNumberAtan2:
1122 case IrOpcode::kNumberMax:
1123 case IrOpcode::kNumberMin:
1124 case IrOpcode::kNumberPow:
1125 CheckValueInputIs(node, 0, Type::Number());
1126 CheckValueInputIs(node, 1, Type::Number());
1127 CheckTypeIs(node, Type::Number());
1128 break;
1129 case IrOpcode::kNumberAbs:
1130 case IrOpcode::kNumberCeil:
1131 case IrOpcode::kNumberFloor:
1132 case IrOpcode::kNumberFround:
1133 case IrOpcode::kNumberAcos:
1134 case IrOpcode::kNumberAcosh:
1135 case IrOpcode::kNumberAsin:
1136 case IrOpcode::kNumberAsinh:
1137 case IrOpcode::kNumberAtan:
1138 case IrOpcode::kNumberAtanh:
1139 case IrOpcode::kNumberCos:
1140 case IrOpcode::kNumberCosh:
1141 case IrOpcode::kNumberExp:
1142 case IrOpcode::kNumberExpm1:
1143 case IrOpcode::kNumberLog:
1144 case IrOpcode::kNumberLog1p:
1145 case IrOpcode::kNumberLog2:
1146 case IrOpcode::kNumberLog10:
1147 case IrOpcode::kNumberCbrt:
1148 case IrOpcode::kNumberRound:
1149 case IrOpcode::kNumberSign:
1150 case IrOpcode::kNumberSin:
1151 case IrOpcode::kNumberSinh:
1152 case IrOpcode::kNumberSqrt:
1153 case IrOpcode::kNumberTan:
1154 case IrOpcode::kNumberTanh:
1155 case IrOpcode::kNumberTrunc:
1156 CheckValueInputIs(node, 0, Type::Number());
1157 CheckTypeIs(node, Type::Number());
1158 break;
1159 case IrOpcode::kNumberToBoolean:
1160 CheckValueInputIs(node, 0, Type::Number());
1161 CheckTypeIs(node, Type::Boolean());
1162 break;
1163 case IrOpcode::kNumberToInt32:
1164 CheckValueInputIs(node, 0, Type::Number());
1165 CheckTypeIs(node, Type::Signed32());
1166 break;
1167 case IrOpcode::kNumberToString:
1168 CheckValueInputIs(node, 0, Type::Number());
1169 CheckTypeIs(node, Type::String());
1170 break;
1171 case IrOpcode::kNumberToUint32:
1172 case IrOpcode::kNumberToUint8Clamped:
1173 CheckValueInputIs(node, 0, Type::Number());
1174 CheckTypeIs(node, Type::Unsigned32());
1175 break;
1176 case IrOpcode::kIntegral32OrMinusZeroToBigInt:
1177 CheckValueInputIs(node, 0, Type::Integral32OrMinusZero());
1178 CheckTypeIs(node, Type::BigInt());
1179 break;
1180 case IrOpcode::kUnsigned32Divide:
1181 CheckValueInputIs(node, 0, Type::Unsigned32());
1182 CheckValueInputIs(node, 1, Type::Unsigned32());
1183 CheckTypeIs(node, Type::Unsigned32());
1184 break;
1185 case IrOpcode::kSpeculativeToNumber:
1186 CheckValueInputIs(node, 0, Type::Any());
1187 CheckTypeIs(node, Type::Number());
1188 break;
1189 case IrOpcode::kPlainPrimitiveToNumber:
1190 CheckValueInputIs(node, 0, Type::PlainPrimitive());
1191 CheckTypeIs(node, Type::Number());
1192 break;
1193 case IrOpcode::kPlainPrimitiveToWord32:
1194 CheckValueInputIs(node, 0, Type::PlainPrimitive());
1195 CheckTypeIs(node, Type::Integral32());
1196 break;
1197 case IrOpcode::kPlainPrimitiveToFloat64:
1198 CheckValueInputIs(node, 0, Type::PlainPrimitive());
1199 CheckTypeIs(node, Type::Number());
1200 break;
1201 case IrOpcode::kStringConcat:
1202 CheckValueInputIs(node, 0, TypeCache::Get()->kStringLengthType);
1203 CheckValueInputIs(node, 1, Type::String());
1204 CheckValueInputIs(node, 2, Type::String());
1205 CheckTypeIs(node, Type::String());
1206 break;
1207 case IrOpcode::kStringEqual:
1208 case IrOpcode::kStringLessThan:
1209 case IrOpcode::kStringLessThanOrEqual:
1210 CheckValueInputIs(node, 0, Type::String());
1211 CheckValueInputIs(node, 1, Type::String());
1212 CheckTypeIs(node, Type::Boolean());
1213 break;
1214 case IrOpcode::kStringToNumber:
1215 CheckValueInputIs(node, 0, Type::String());
1216 CheckTypeIs(node, Type::Number());
1217 break;
1218 case IrOpcode::kStringCharCodeAt:
1219 CheckValueInputIs(node, 0, Type::String());
1220 CheckValueInputIs(node, 1, Type::Unsigned32());
1221 CheckTypeIs(node, Type::UnsignedSmall());
1222 break;
1223 case IrOpcode::kStringCodePointAt:
1224 CheckValueInputIs(node, 0, Type::String());
1225 CheckValueInputIs(node, 1, Type::Unsigned32());
1226 CheckTypeIs(node, Type::UnsignedSmall());
1227 break;
1228 case IrOpcode::kStringFromSingleCharCode:
1229 CheckValueInputIs(node, 0, Type::Number());
1230 CheckTypeIs(node, Type::String());
1231 break;
1232 case IrOpcode::kStringFromSingleCodePoint:
1233 CheckValueInputIs(node, 0, Type::Number());
1234 CheckTypeIs(node, Type::String());
1235 break;
1236 case IrOpcode::kStringFromCodePointAt:
1237 CheckValueInputIs(node, 0, Type::String());
1238 CheckValueInputIs(node, 1, Type::Unsigned32());
1239 CheckTypeIs(node, Type::String());
1240 break;
1241 case IrOpcode::kStringIndexOf:
1242 CheckValueInputIs(node, 0, Type::String());
1243 CheckValueInputIs(node, 1, Type::String());
1244 CheckValueInputIs(node, 2, Type::SignedSmall());
1245 CheckTypeIs(node, Type::SignedSmall());
1246 break;
1247 case IrOpcode::kStringLength:
1248 CheckValueInputIs(node, 0, Type::String());
1249 CheckTypeIs(node, TypeCache::Get()->kStringLengthType);
1250 break;
1251 case IrOpcode::kStringWrapperLength:
1252 CheckValueInputIs(node, 0, Type::StringWrapper());
1253 CheckTypeIs(node, TypeCache::Get()->kStringLengthType);
1254 break;
1255 case IrOpcode::kTypedArrayLength:
1256 CheckValueInputIs(node, 0, Type::TypedArray());
1257 CheckTypeIs(node, TypeCache::Get()->kJSTypedArrayLengthType);
1258 break;
1259 case IrOpcode::kStringToLowerCaseIntl:
1260 case IrOpcode::kStringToUpperCaseIntl:
1261 CheckValueInputIs(node, 0, Type::String());
1262 CheckTypeIs(node, Type::String());
1263 break;
1264 case IrOpcode::kStringSubstring:
1265 CheckValueInputIs(node, 0, Type::String());
1266 CheckValueInputIs(node, 1, Type::SignedSmall());
1267 CheckValueInputIs(node, 2, Type::SignedSmall());
1268 CheckTypeIs(node, Type::String());
1269 break;
1270 case IrOpcode::kReferenceEqual:
1271 CheckTypeIs(node, Type::Boolean());
1272 break;
1273 case IrOpcode::kSameValue:
1274 case IrOpcode::kSameValueNumbersOnly:
1275 CheckValueInputIs(node, 0, Type::Any());
1276 CheckValueInputIs(node, 1, Type::Any());
1277 CheckTypeIs(node, Type::Boolean());
1278 break;
1279 case IrOpcode::kNumberSameValue:
1280 CheckValueInputIs(node, 0, Type::Number());
1281 CheckValueInputIs(node, 1, Type::Number());
1282 CheckTypeIs(node, Type::Boolean());
1283 break;
1284 case IrOpcode::kObjectIsArrayBufferView:
1285 case IrOpcode::kObjectIsBigInt:
1286 case IrOpcode::kObjectIsCallable:
1287 case IrOpcode::kObjectIsConstructor:
1288 case IrOpcode::kObjectIsDetectableCallable:
1289 case IrOpcode::kObjectIsMinusZero:
1290 case IrOpcode::kObjectIsNaN:
1291 case IrOpcode::kObjectIsNonCallable:
1292 case IrOpcode::kObjectIsNumber:
1293 case IrOpcode::kObjectIsReceiver:
1294 case IrOpcode::kObjectIsSmi:
1295 case IrOpcode::kObjectIsString:
1296 case IrOpcode::kObjectIsSymbol:
1297 case IrOpcode::kObjectIsUndetectable:
1298 CheckValueInputIs(node, 0, Type::Any());
1299 CheckTypeIs(node, Type::Boolean());
1300 break;
1301 case IrOpcode::kNumberIsFloat64Hole:
1302 CheckValueInputIs(node, 0, Type::NumberOrHole());
1303 CheckTypeIs(node, Type::Boolean());
1304 break;
1305 case IrOpcode::kNumberIsFinite:
1306 case IrOpcode::kNumberIsMinusZero:
1307 case IrOpcode::kNumberIsNaN:
1308 CheckValueInputIs(node, 0, Type::Number());
1309 CheckTypeIs(node, Type::Boolean());
1310 break;
1311 case IrOpcode::kObjectIsFiniteNumber:
1312 CheckValueInputIs(node, 0, Type::Any());
1313 CheckTypeIs(node, Type::Boolean());
1314 break;
1315 case IrOpcode::kNumberIsInteger:
1316 CheckValueInputIs(node, 0, Type::Number());
1317 CheckTypeIs(node, Type::Boolean());
1318 break;
1319 case IrOpcode::kObjectIsSafeInteger:
1320 CheckValueInputIs(node, 0, Type::Any());
1321 CheckTypeIs(node, Type::Boolean());
1322 break;
1323 case IrOpcode::kNumberIsSafeInteger:
1324 CheckValueInputIs(node, 0, Type::Number());
1325 CheckTypeIs(node, Type::Boolean());
1326 break;
1327 case IrOpcode::kObjectIsInteger:
1328 CheckValueInputIs(node, 0, Type::Any());
1329 CheckTypeIs(node, Type::Boolean());
1330 break;
1331 case IrOpcode::kFindOrderedHashMapEntry:
1332 CheckValueInputIs(node, 0, Type::Any());
1333 CheckTypeIs(node, Type::SignedSmall());
1334 break;
1335 case IrOpcode::kFindOrderedHashMapEntryForInt32Key:
1336 CheckValueInputIs(node, 0, Type::Any());
1337 CheckValueInputIs(node, 1, Type::Signed32());
1338 CheckTypeIs(node, Type::SignedSmall());
1339 break;
1340 case IrOpcode::kFindOrderedHashSetEntry:
1341 CheckValueInputIs(node, 0, Type::Any());
1342 CheckTypeIs(node, Type::SignedSmall());
1343 break;
1344 case IrOpcode::kArgumentsLength:
1345 case IrOpcode::kRestLength:
1346 CheckTypeIs(node, TypeCache::Get()->kArgumentsLengthType);
1347 break;
1348 case IrOpcode::kNewDoubleElements:
1349 case IrOpcode::kNewSmiOrObjectElements:
1350 CheckValueInputIs(node, 0,
1352 CheckTypeIs(node, Type::OtherInternal());
1353 break;
1354 case IrOpcode::kNewArgumentsElements:
1355 CheckValueInputIs(node, 0,
1357 CheckTypeIs(node, Type::OtherInternal());
1358 break;
1359 case IrOpcode::kNewConsString:
1360 CheckValueInputIs(node, 0, TypeCache::Get()->kStringLengthType);
1361 CheckValueInputIs(node, 1, Type::String());
1362 CheckValueInputIs(node, 2, Type::String());
1363 CheckTypeIs(node, Type::String());
1364 break;
1365 case IrOpcode::kAllocate:
1366 CheckValueInputIs(node, 0, Type::PlainNumber());
1367 break;
1368 case IrOpcode::kAllocateRaw:
1369 // CheckValueInputIs(node, 0, Type::PlainNumber());
1370 break;
1371 case IrOpcode::kEnsureWritableFastElements:
1372 CheckValueInputIs(node, 0, Type::Any());
1373 CheckValueInputIs(node, 1, Type::Internal());
1374 CheckTypeIs(node, Type::Internal());
1375 break;
1376 case IrOpcode::kMaybeGrowFastElements:
1377 CheckValueInputIs(node, 0, Type::Any());
1378 CheckValueInputIs(node, 1, Type::Internal());
1379 CheckValueInputIs(node, 2, Type::Unsigned31());
1380 CheckValueInputIs(node, 3, Type::Unsigned31());
1381 CheckTypeIs(node, Type::Internal());
1382 break;
1383 case IrOpcode::kTransitionElementsKind:
1384 CheckValueInputIs(node, 0, Type::Any());
1385 CheckNotTyped(node);
1386 break;
1387 case IrOpcode::kTransitionElementsKindOrCheckMap:
1388 CheckValueInputIs(node, 0, Type::Any());
1389 CheckNotTyped(node);
1390 break;
1391
1392 case IrOpcode::kChangeTaggedSignedToInt32: {
1393 // Signed32 /\ Tagged -> Signed32 /\ UntaggedInt32
1394 // TODO(neis): Activate once ChangeRepresentation works in typer.
1395 // Type from = Type::Intersect(Type::Signed32(), Type::Tagged());
1396 // Type to = Type::Intersect(Type::Signed32(), Type::UntaggedInt32());
1397 // CheckValueInputIs(node, 0, from));
1398 // CheckTypeIs(node, to));
1399 break;
1400 }
1401 case IrOpcode::kChangeTaggedSignedToInt64:
1402 break;
1403 case IrOpcode::kChangeTaggedToInt32: {
1404 // Signed32 /\ Tagged -> Signed32 /\ UntaggedInt32
1405 // TODO(neis): Activate once ChangeRepresentation works in typer.
1406 // Type from = Type::Intersect(Type::Signed32(), Type::Tagged());
1407 // Type to = Type::Intersect(Type::Signed32(), Type::UntaggedInt32());
1408 // CheckValueInputIs(node, 0, from));
1409 // CheckTypeIs(node, to));
1410 break;
1411 }
1412 case IrOpcode::kChangeTaggedToInt64:
1413 break;
1414 case IrOpcode::kChangeTaggedToUint32: {
1415 // Unsigned32 /\ Tagged -> Unsigned32 /\ UntaggedInt32
1416 // TODO(neis): Activate once ChangeRepresentation works in typer.
1417 // Type from = Type::Intersect(Type::Unsigned32(), Type::Tagged());
1418 // Type to =Type::Intersect(Type::Unsigned32(), Type::UntaggedInt32());
1419 // CheckValueInputIs(node, 0, from));
1420 // CheckTypeIs(node, to));
1421 break;
1422 }
1423 case IrOpcode::kChangeTaggedToFloat64: {
1424 // NumberOrUndefined /\ Tagged -> Number /\ UntaggedFloat64
1425 // TODO(neis): Activate once ChangeRepresentation works in typer.
1426 // Type from = Type::Intersect(Type::Number(), Type::Tagged());
1427 // Type to = Type::Intersect(Type::Number(), Type::UntaggedFloat64());
1428 // CheckValueInputIs(node, 0, from));
1429 // CheckTypeIs(node, to));
1430 break;
1431 }
1432 case IrOpcode::kChangeTaggedToTaggedSigned: // Fall through.
1433 break;
1434 case IrOpcode::kTruncateTaggedToFloat64: {
1435 // NumberOrUndefined /\ Tagged -> Number /\ UntaggedFloat64
1436 // TODO(neis): Activate once ChangeRepresentation works in typer.
1437 // Type from = Type::Intersect(Type::NumberOrUndefined(),
1438 // Type::Tagged());
1439 // Type to = Type::Intersect(Type::Number(), Type::UntaggedFloat64());
1440 // CheckValueInputIs(node, 0, from));
1441 // CheckTypeIs(node, to));
1442 break;
1443 }
1444 case IrOpcode::kChangeInt31ToTaggedSigned: {
1445 // Signed31 /\ UntaggedInt32 -> Signed31 /\ Tagged
1446 // TODO(neis): Activate once ChangeRepresentation works in typer.
1447 // Type from =Type::Intersect(Type::Signed31(), Type::UntaggedInt32());
1448 // Type to = Type::Intersect(Type::Signed31(), Type::Tagged());
1449 // CheckValueInputIs(node, 0, from));
1450 // CheckTypeIs(node, to));
1451 break;
1452 }
1453 case IrOpcode::kChangeInt32ToTagged: {
1454 // Signed32 /\ UntaggedInt32 -> Signed32 /\ Tagged
1455 // TODO(neis): Activate once ChangeRepresentation works in typer.
1456 // Type from =Type::Intersect(Type::Signed32(), Type::UntaggedInt32());
1457 // Type to = Type::Intersect(Type::Signed32(), Type::Tagged());
1458 // CheckValueInputIs(node, 0, from));
1459 // CheckTypeIs(node, to));
1460 break;
1461 }
1462 case IrOpcode::kChangeInt64ToTagged:
1463 break;
1464 case IrOpcode::kChangeUint32ToTagged: {
1465 // Unsigned32 /\ UntaggedInt32 -> Unsigned32 /\ Tagged
1466 // TODO(neis): Activate once ChangeRepresentation works in typer.
1467 // Type from=Type::Intersect(Type::Unsigned32(),Type::UntaggedInt32());
1468 // Type to = Type::Intersect(Type::Unsigned32(), Type::Tagged());
1469 // CheckValueInputIs(node, 0, from));
1470 // CheckTypeIs(node, to));
1471 break;
1472 }
1473 case IrOpcode::kChangeUint64ToTagged:
1474 break;
1475 case IrOpcode::kChangeFloat64ToTagged: {
1476 // Number /\ UntaggedFloat64 -> Number /\ Tagged
1477 // TODO(neis): Activate once ChangeRepresentation works in typer.
1478 // Type from =Type::Intersect(Type::Number(), Type::UntaggedFloat64());
1479 // Type to = Type::Intersect(Type::Number(), Type::Tagged());
1480 // CheckValueInputIs(node, 0, from));
1481 // CheckTypeIs(node, to));
1482 break;
1483 }
1484 case IrOpcode::kChangeFloat64ToTaggedPointer:
1485 break;
1486 case IrOpcode::kChangeTaggedToBit: {
1487 // Boolean /\ TaggedPtr -> Boolean /\ UntaggedInt1
1488 // TODO(neis): Activate once ChangeRepresentation works in typer.
1489 // Type from = Type::Intersect(Type::Boolean(), Type::TaggedPtr());
1490 // Type to = Type::Intersect(Type::Boolean(), Type::UntaggedInt1());
1491 // CheckValueInputIs(node, 0, from));
1492 // CheckTypeIs(node, to));
1493 break;
1494 }
1495 case IrOpcode::kChangeBitToTagged: {
1496 // Boolean /\ UntaggedInt1 -> Boolean /\ TaggedPtr
1497 // TODO(neis): Activate once ChangeRepresentation works in typer.
1498 // Type from = Type::Intersect(Type::Boolean(), Type::UntaggedInt1());
1499 // Type to = Type::Intersect(Type::Boolean(), Type::TaggedPtr());
1500 // CheckValueInputIs(node, 0, from));
1501 // CheckTypeIs(node, to));
1502 break;
1503 }
1504 case IrOpcode::kTruncateTaggedToWord32: {
1505 // Number /\ Tagged -> Signed32 /\ UntaggedInt32
1506 // TODO(neis): Activate once ChangeRepresentation works in typer.
1507 // Type from = Type::Intersect(Type::Number(), Type::Tagged());
1508 // Type to = Type::Intersect(Type::Number(), Type::UntaggedInt32());
1509 // CheckValueInputIs(node, 0, from));
1510 // CheckTypeIs(node, to));
1511 break;
1512 }
1513 case IrOpcode::kTruncateBigIntToWord64:
1514 CheckValueInputIs(node, 0, Type::BigInt());
1515 CheckTypeIs(node, Type::BigInt());
1516 break;
1517 case IrOpcode::kChangeInt64ToBigInt:
1518 CheckValueInputIs(node, 0, Type::SignedBigInt64());
1519 CheckTypeIs(node, Type::SignedBigInt64());
1520 break;
1521 case IrOpcode::kChangeUint64ToBigInt:
1522 CheckValueInputIs(node, 0, Type::UnsignedBigInt64());
1523 CheckTypeIs(node, Type::UnsignedBigInt64());
1524 break;
1525 case IrOpcode::kTruncateTaggedToBit:
1526 case IrOpcode::kTruncateTaggedPointerToBit:
1527 break;
1528
1529 case IrOpcode::kCheckBounds:
1530 CheckValueInputIs(node, 0, Type::Any());
1531 CheckValueInputIs(node, 1, TypeCache::Get()->kPositiveSafeInteger);
1532 CheckTypeIs(node, TypeCache::Get()->kPositiveSafeInteger);
1533 break;
1534 case IrOpcode::kCheckClosure:
1535 // Any -> Function
1536 CheckValueInputIs(node, 0, Type::Any());
1537 CheckTypeIs(node, Type::Function());
1538 break;
1539 case IrOpcode::kCheckHeapObject:
1540 CheckValueInputIs(node, 0, Type::Any());
1541 break;
1542 case IrOpcode::kCheckIf:
1543 CheckValueInputIs(node, 0, Type::Boolean());
1544 CheckNotTyped(node);
1545 break;
1546 case IrOpcode::kCheckInternalizedString:
1547 CheckValueInputIs(node, 0, Type::Any());
1548 CheckTypeIs(node, Type::InternalizedString());
1549 break;
1550 case IrOpcode::kCheckMaps:
1551 CheckValueInputIs(node, 0, Type::Any());
1552 CheckNotTyped(node);
1553 break;
1554 case IrOpcode::kCompareMaps:
1555 CheckValueInputIs(node, 0, Type::Any());
1556 CheckTypeIs(node, Type::Boolean());
1557 break;
1558 case IrOpcode::kCheckNumber:
1559 CheckValueInputIs(node, 0, Type::Any());
1560 CheckTypeIs(node, Type::Number());
1561 break;
1562 case IrOpcode::kCheckNumberFitsInt32:
1563 CheckValueInputIs(node, 0, Type::Any());
1564 CheckTypeIs(node, Type::Signed32());
1565 break;
1566 case IrOpcode::kCheckReceiver:
1567 CheckValueInputIs(node, 0, Type::Any());
1568 CheckTypeIs(node, Type::Receiver());
1569 break;
1570 case IrOpcode::kCheckReceiverOrNullOrUndefined:
1571 CheckValueInputIs(node, 0, Type::Any());
1572 CheckTypeIs(node, Type::ReceiverOrNullOrUndefined());
1573 break;
1574 case IrOpcode::kCheckSmi:
1575 CheckValueInputIs(node, 0, Type::Any());
1576 break;
1577 case IrOpcode::kCheckString:
1578 CheckValueInputIs(node, 0, Type::Any());
1579 CheckTypeIs(node, Type::String());
1580 break;
1581 case IrOpcode::kCheckStringOrStringWrapper:
1582 CheckValueInputIs(node, 0, Type::Any());
1583 CheckTypeIs(node, Type::StringOrStringWrapper());
1584 break;
1585 case IrOpcode::kCheckSymbol:
1586 CheckValueInputIs(node, 0, Type::Any());
1587 CheckTypeIs(node, Type::Symbol());
1588 break;
1589 case IrOpcode::kConvertReceiver:
1590 CheckValueInputIs(node, 0, Type::Any());
1591 CheckValueInputIs(node, 1, Type::Any());
1592 CheckValueInputIs(node, 2, Type::Any());
1593 CheckTypeIs(node, Type::Receiver());
1594 break;
1595
1596 case IrOpcode::kCheckedInt32Add:
1597 case IrOpcode::kCheckedInt32Sub:
1598 case IrOpcode::kCheckedInt32Div:
1599 case IrOpcode::kCheckedInt32Mod:
1600 case IrOpcode::kCheckedUint32Div:
1601 case IrOpcode::kCheckedUint32Mod:
1602 case IrOpcode::kCheckedInt32Mul:
1603 case IrOpcode::kCheckedInt32ToTaggedSigned:
1604 case IrOpcode::kCheckedInt64ToInt32:
1605 case IrOpcode::kCheckedInt64ToTaggedSigned:
1606 case IrOpcode::kCheckedUint32Bounds:
1607 case IrOpcode::kCheckedUint32ToInt32:
1608 case IrOpcode::kCheckedUint32ToTaggedSigned:
1609 case IrOpcode::kCheckedUint64Bounds:
1610 case IrOpcode::kCheckedUint64ToInt32:
1611 case IrOpcode::kCheckedUint64ToInt64:
1612 case IrOpcode::kCheckedUint64ToTaggedSigned:
1613 case IrOpcode::kCheckedFloat64ToInt32:
1614 case IrOpcode::kCheckedFloat64ToAdditiveSafeInteger:
1615 case IrOpcode::kCheckedFloat64ToInt64:
1616 case IrOpcode::kCheckedTaggedSignedToInt32:
1617 case IrOpcode::kCheckedTaggedToInt32:
1618 case IrOpcode::kCheckedTaggedToArrayIndex:
1619 case IrOpcode::kCheckedTaggedToAdditiveSafeInteger:
1620 case IrOpcode::kCheckedTaggedToInt64:
1621 case IrOpcode::kCheckedTaggedToFloat64:
1622 case IrOpcode::kCheckedTaggedToTaggedSigned:
1623 case IrOpcode::kCheckedTaggedToTaggedPointer:
1624 case IrOpcode::kCheckedTruncateTaggedToWord32:
1625 case IrOpcode::kCheckedAdditiveSafeIntegerAdd:
1626 case IrOpcode::kCheckedAdditiveSafeIntegerSub:
1627 case IrOpcode::kCheckedInt64Add:
1628 case IrOpcode::kCheckedInt64Sub:
1629 case IrOpcode::kCheckedInt64Mul:
1630 case IrOpcode::kCheckedInt64Div:
1631 case IrOpcode::kCheckedInt64Mod:
1632 case IrOpcode::kAssertType:
1633 case IrOpcode::kVerifyType:
1634 case IrOpcode::kCheckTurboshaftTypeOf:
1635 break;
1636 case IrOpcode::kDoubleArrayMin:
1637 case IrOpcode::kDoubleArrayMax:
1638 CheckValueInputIs(node, 0, Type::Any());
1639 CheckTypeIs(node, Type::Number());
1640 break;
1641 case IrOpcode::kCheckFloat64Hole:
1642 CheckValueInputIs(node, 0, Type::NumberOrHole());
1643 CheckTypeIs(node, Type::NumberOrUndefined());
1644 break;
1645 case IrOpcode::kChangeFloat64HoleToTagged:
1646 CheckValueInputIs(node, 0, Type::NumberOrHole());
1647 CheckTypeIs(node, Type::NumberOrUndefined());
1648 break;
1649 case IrOpcode::kCheckNotTaggedHole:
1650 CheckValueInputIs(node, 0, Type::Any());
1651 CheckTypeIs(node, Type::NonInternal());
1652 break;
1653 case IrOpcode::kConvertTaggedHoleToUndefined:
1654 CheckValueInputIs(node, 0, Type::Any());
1655 CheckTypeIs(node, Type::NonInternal());
1656 break;
1657
1658 case IrOpcode::kCheckEqualsInternalizedString:
1659 CheckValueInputIs(node, 0, Type::InternalizedString());
1660 CheckValueInputIs(node, 1, Type::Any());
1661 CheckNotTyped(node);
1662 break;
1663 case IrOpcode::kCheckEqualsSymbol:
1664 CheckValueInputIs(node, 0, Type::Symbol());
1665 CheckValueInputIs(node, 1, Type::Any());
1666 CheckNotTyped(node);
1667 break;
1668
1669 case IrOpcode::kLoadFieldByIndex:
1670 CheckValueInputIs(node, 0, Type::Any());
1671 CheckValueInputIs(node, 1, Type::SignedSmall());
1672 CheckTypeIs(node, Type::NonInternal());
1673 break;
1674 case IrOpcode::kLoadField:
1675 case IrOpcode::kLoadMessage:
1676 // Object -> fieldtype
1677 // TODO(rossberg): activate once machine ops are typed.
1678 // CheckValueInputIs(node, 0, Type::Object());
1679 // CheckTypeIs(node, FieldAccessOf(node->op()).type);
1680 break;
1681 case IrOpcode::kLoadElement:
1682 case IrOpcode::kLoadStackArgument:
1683 // Object -> elementtype
1684 // TODO(rossberg): activate once machine ops are typed.
1685 // CheckValueInputIs(node, 0, Type::Object());
1686 // CheckTypeIs(node, ElementAccessOf(node->op()).type));
1687 break;
1688 case IrOpcode::kLoadFromObject:
1689 case IrOpcode::kLoadImmutableFromObject:
1690 CheckValueInputIs(node, 0, Type::Receiver());
1691 break;
1692 case IrOpcode::kLoadTypedElement:
1693 break;
1694 case IrOpcode::kLoadDataViewElement:
1695 break;
1696 case IrOpcode::kStoreField:
1697 case IrOpcode::kStoreMessage:
1698 // (Object, fieldtype) -> _|_
1699 // TODO(rossberg): activate once machine ops are typed.
1700 // CheckValueInputIs(node, 0, Type::Object());
1701 // CheckValueInputIs(node, 1, FieldAccessOf(node->op()).type));
1702 CheckNotTyped(node);
1703 break;
1704 case IrOpcode::kStoreElement:
1705 // (Object, elementtype) -> _|_
1706 // TODO(rossberg): activate once machine ops are typed.
1707 // CheckValueInputIs(node, 0, Type::Object());
1708 // CheckValueInputIs(node, 1, ElementAccessOf(node->op()).type));
1709 CheckNotTyped(node);
1710 break;
1711 case IrOpcode::kStoreToObject:
1712 case IrOpcode::kInitializeImmutableInObject:
1713 // TODO(gsps): Can we check some types here?
1714 break;
1715 case IrOpcode::kTransitionAndStoreElement:
1716 CheckNotTyped(node);
1717 break;
1718 case IrOpcode::kTransitionAndStoreNumberElement:
1719 CheckNotTyped(node);
1720 break;
1721 case IrOpcode::kTransitionAndStoreNonNumberElement:
1722 CheckNotTyped(node);
1723 break;
1724 case IrOpcode::kStoreSignedSmallElement:
1725 CheckNotTyped(node);
1726 break;
1727 case IrOpcode::kStoreTypedElement:
1728 CheckNotTyped(node);
1729 break;
1730 case IrOpcode::kStoreDataViewElement:
1731 CheckNotTyped(node);
1732 break;
1733 case IrOpcode::kNumberSilenceNaN:
1734 CheckValueInputIs(node, 0, Type::Number());
1735 CheckTypeIs(node, Type::Number());
1736 break;
1737 case IrOpcode::kMapGuard:
1738 CheckNotTyped(node);
1739 break;
1740 case IrOpcode::kTypeGuard:
1741 CheckTypeIs(node, TypeGuardTypeOf(node->op()));
1742 break;
1743 case IrOpcode::kDateNow:
1744 CHECK_EQ(0, value_count);
1745 CheckTypeIs(node, Type::Number());
1746 break;
1747 case IrOpcode::kCheckBigInt:
1748 CheckValueInputIs(node, 0, Type::Any());
1749 CheckTypeIs(node, Type::BigInt());
1750 break;
1751 case IrOpcode::kCheckedBigIntToBigInt64:
1752 CheckValueInputIs(node, 0, Type::BigInt());
1753 CheckTypeIs(node, Type::SignedBigInt64());
1754 break;
1755 case IrOpcode::kFastApiCall:
1756 CHECK_GE(value_count, 1);
1757 CheckValueInputIs(node, 0, Type::Any()); // receiver
1758 break;
1759#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
1760 case IrOpcode::kGetContinuationPreservedEmbedderData:
1761 CHECK_EQ(value_count, 0);
1762 CHECK_EQ(effect_count, 1);
1763 CheckTypeIs(node, Type::Any());
1764 break;
1765 case IrOpcode::kSetContinuationPreservedEmbedderData:
1766 CHECK_EQ(value_count, 1);
1767 CHECK_EQ(effect_count, 1);
1768 CheckValueInputIs(node, 0, Type::Any());
1769 CheckNotTyped(node);
1770 break;
1771#endif // V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
1772 case IrOpcode::kSLVerifierHint:
1773 // SLVerifierHint is internal to SimplifiedLowering and should never be
1774 // seen by the verifier.
1775 UNREACHABLE();
1776#if V8_ENABLE_WEBASSEMBLY
1777 case IrOpcode::kJSWasmCall:
1778 CHECK_GE(value_count, 3);
1779 CheckTypeIs(node, Type::Any());
1780 CheckValueInputIs(node, 0, Type::Any()); // callee
1781 break;
1782 case IrOpcode::kWasmTypeCheck:
1783 case IrOpcode::kWasmTypeCheckAbstract:
1784 case IrOpcode::kWasmTypeCast:
1785 case IrOpcode::kWasmTypeCastAbstract:
1786 case IrOpcode::kRttCanon:
1787 case IrOpcode::kNull:
1788 case IrOpcode::kIsNull:
1789 case IrOpcode::kIsNotNull:
1790 case IrOpcode::kAssertNotNull:
1791 case IrOpcode::kWasmAnyConvertExtern:
1792 case IrOpcode::kWasmExternConvertAny:
1793 case IrOpcode::kWasmStructGet:
1794 case IrOpcode::kWasmStructSet:
1795 case IrOpcode::kWasmArrayGet:
1796 case IrOpcode::kWasmArraySet:
1797 case IrOpcode::kWasmArrayLength:
1798 case IrOpcode::kWasmArrayInitializeLength:
1799 case IrOpcode::kStringAsWtf16:
1800 case IrOpcode::kStringPrepareForGetCodeunit:
1801 case IrOpcode::kLoadStackPointer:
1802 case IrOpcode::kSetStackPointer:
1803 // TODO(7748): What are the constraints here?
1804 break;
1805#endif // V8_ENABLE_WEBASSEMBLY
1806
1807 // Machine operators
1808 // -----------------------
1809 case IrOpcode::kLoad:
1810 case IrOpcode::kLoadImmutable:
1811 case IrOpcode::kProtectedLoad:
1812 case IrOpcode::kProtectedStore:
1813 case IrOpcode::kLoadTrapOnNull:
1814 case IrOpcode::kStoreTrapOnNull:
1815 case IrOpcode::kStore:
1816 case IrOpcode::kStorePair:
1817 case IrOpcode::kStoreIndirectPointer:
1818 case IrOpcode::kStackSlot:
1819 case IrOpcode::kWord32And:
1820 case IrOpcode::kWord32Or:
1821 case IrOpcode::kWord32Xor:
1822 case IrOpcode::kWord32Shl:
1823 case IrOpcode::kWord32Shr:
1824 case IrOpcode::kWord32Sar:
1825 case IrOpcode::kWord32Rol:
1826 case IrOpcode::kWord32Ror:
1827 case IrOpcode::kWord32Equal:
1828 case IrOpcode::kWord32Clz:
1829 case IrOpcode::kWord32Ctz:
1830 case IrOpcode::kWord32ReverseBits:
1831 case IrOpcode::kWord32ReverseBytes:
1832 case IrOpcode::kInt32AbsWithOverflow:
1833 case IrOpcode::kWord32Popcnt:
1834 case IrOpcode::kWord64And:
1835 case IrOpcode::kWord64Or:
1836 case IrOpcode::kWord64Xor:
1837 case IrOpcode::kWord64Shl:
1838 case IrOpcode::kWord64Shr:
1839 case IrOpcode::kWord64Sar:
1840 case IrOpcode::kWord64Rol:
1841 case IrOpcode::kWord64Ror:
1842 case IrOpcode::kWord64Clz:
1843 case IrOpcode::kWord64Ctz:
1844 case IrOpcode::kWord64RolLowerable:
1845 case IrOpcode::kWord64RorLowerable:
1846 case IrOpcode::kWord64ClzLowerable:
1847 case IrOpcode::kWord64CtzLowerable:
1848 case IrOpcode::kWord64Popcnt:
1849 case IrOpcode::kWord64ReverseBits:
1850 case IrOpcode::kWord64ReverseBytes:
1851 case IrOpcode::kSimd128ReverseBytes:
1852 case IrOpcode::kInt64AbsWithOverflow:
1853 case IrOpcode::kWord64Equal:
1854 case IrOpcode::kInt32Add:
1855 case IrOpcode::kInt32AddWithOverflow:
1856 case IrOpcode::kInt32Sub:
1857 case IrOpcode::kInt32SubWithOverflow:
1858 case IrOpcode::kInt32Mul:
1859 case IrOpcode::kInt32MulWithOverflow:
1860 case IrOpcode::kInt32MulHigh:
1861 case IrOpcode::kInt32Div:
1862 case IrOpcode::kInt32Mod:
1863 case IrOpcode::kInt32LessThan:
1864 case IrOpcode::kInt32LessThanOrEqual:
1865 case IrOpcode::kUint32Div:
1866 case IrOpcode::kUint32Mod:
1867 case IrOpcode::kUint32MulHigh:
1868 case IrOpcode::kUint32LessThan:
1869 case IrOpcode::kUint32LessThanOrEqual:
1870 case IrOpcode::kInt64Add:
1871 case IrOpcode::kInt64AddWithOverflow:
1872 case IrOpcode::kInt64Sub:
1873 case IrOpcode::kInt64SubWithOverflow:
1874 case IrOpcode::kInt64Mul:
1875 case IrOpcode::kInt64MulHigh:
1876 case IrOpcode::kInt64MulWithOverflow:
1877 case IrOpcode::kInt64Div:
1878 case IrOpcode::kInt64Mod:
1879 case IrOpcode::kInt64LessThan:
1880 case IrOpcode::kInt64LessThanOrEqual:
1881 case IrOpcode::kUint64Div:
1882 case IrOpcode::kUint64Mod:
1883 case IrOpcode::kUint64MulHigh:
1884 case IrOpcode::kUint64LessThan:
1885 case IrOpcode::kUint64LessThanOrEqual:
1886 case IrOpcode::kFloat32Add:
1887 case IrOpcode::kFloat32Sub:
1888 case IrOpcode::kFloat32Neg:
1889 case IrOpcode::kFloat32Mul:
1890 case IrOpcode::kFloat32Div:
1891 case IrOpcode::kFloat32Abs:
1892 case IrOpcode::kFloat32Sqrt:
1893 case IrOpcode::kFloat32Equal:
1894 case IrOpcode::kFloat32LessThan:
1895 case IrOpcode::kFloat32LessThanOrEqual:
1896 case IrOpcode::kFloat32Max:
1897 case IrOpcode::kFloat32Min:
1898 case IrOpcode::kFloat64Add:
1899 case IrOpcode::kFloat64Sub:
1900 case IrOpcode::kFloat64Neg:
1901 case IrOpcode::kFloat64Mul:
1902 case IrOpcode::kFloat64Div:
1903 case IrOpcode::kFloat64Mod:
1904 case IrOpcode::kFloat64Max:
1905 case IrOpcode::kFloat64Min:
1906 case IrOpcode::kFloat64Abs:
1907 case IrOpcode::kFloat64Acos:
1908 case IrOpcode::kFloat64Acosh:
1909 case IrOpcode::kFloat64Asin:
1910 case IrOpcode::kFloat64Asinh:
1911 case IrOpcode::kFloat64Atan:
1912 case IrOpcode::kFloat64Atan2:
1913 case IrOpcode::kFloat64Atanh:
1914 case IrOpcode::kFloat64Cbrt:
1915 case IrOpcode::kFloat64Cos:
1916 case IrOpcode::kFloat64Cosh:
1917 case IrOpcode::kFloat64Exp:
1918 case IrOpcode::kFloat64Expm1:
1919 case IrOpcode::kFloat64Log:
1920 case IrOpcode::kFloat64Log1p:
1921 case IrOpcode::kFloat64Log10:
1922 case IrOpcode::kFloat64Log2:
1923 case IrOpcode::kFloat64Pow:
1924 case IrOpcode::kFloat64Sin:
1925 case IrOpcode::kFloat64Sinh:
1926 case IrOpcode::kFloat64Sqrt:
1927 case IrOpcode::kFloat64Tan:
1928 case IrOpcode::kFloat64Tanh:
1929 case IrOpcode::kFloat32RoundDown:
1930 case IrOpcode::kFloat64RoundDown:
1931 case IrOpcode::kFloat32RoundUp:
1932 case IrOpcode::kFloat64RoundUp:
1933 case IrOpcode::kFloat32RoundTruncate:
1934 case IrOpcode::kFloat64RoundTruncate:
1935 case IrOpcode::kFloat64RoundTiesAway:
1936 case IrOpcode::kFloat32RoundTiesEven:
1937 case IrOpcode::kFloat64RoundTiesEven:
1938 case IrOpcode::kFloat64Equal:
1939 case IrOpcode::kFloat64LessThan:
1940 case IrOpcode::kFloat64LessThanOrEqual:
1941 case IrOpcode::kTruncateInt64ToInt32:
1942 case IrOpcode::kRoundFloat64ToInt32:
1943 case IrOpcode::kRoundInt32ToFloat32:
1944 case IrOpcode::kRoundInt64ToFloat32:
1945 case IrOpcode::kRoundInt64ToFloat64:
1946 case IrOpcode::kRoundUint32ToFloat32:
1947 case IrOpcode::kRoundUint64ToFloat64:
1948 case IrOpcode::kRoundUint64ToFloat32:
1949 case IrOpcode::kTruncateFloat64ToFloat32:
1950 case IrOpcode::kChangeFloat16RawBitsToFloat64:
1951 case IrOpcode::kTruncateFloat64ToFloat16RawBits:
1952 case IrOpcode::kTruncateFloat64ToWord32:
1953 case IrOpcode::kBitcastFloat32ToInt32:
1954 case IrOpcode::kBitcastFloat64ToInt64:
1955 case IrOpcode::kBitcastInt32ToFloat32:
1956 case IrOpcode::kBitcastInt64ToFloat64:
1957 case IrOpcode::kBitcastTaggedToWord:
1958 case IrOpcode::kBitcastTaggedToWordForTagAndSmiBits:
1959 case IrOpcode::kBitcastWordToTagged:
1960 case IrOpcode::kBitcastWordToTaggedSigned:
1961 case IrOpcode::kBitcastWord32ToWord64:
1962 case IrOpcode::kChangeInt32ToInt64:
1963 case IrOpcode::kChangeUint32ToUint64:
1964 case IrOpcode::kChangeInt32ToFloat64:
1965 case IrOpcode::kChangeInt64ToFloat64:
1966 case IrOpcode::kChangeUint32ToFloat64:
1967 case IrOpcode::kChangeFloat32ToFloat64:
1968 case IrOpcode::kChangeFloat64ToInt32:
1969 case IrOpcode::kChangeFloat64ToInt64:
1970 case IrOpcode::kChangeFloat64ToUint32:
1971 case IrOpcode::kChangeFloat64ToUint64:
1972 case IrOpcode::kFloat64SilenceNaN:
1973 case IrOpcode::kTruncateFloat64ToInt64:
1974 case IrOpcode::kTruncateFloat64ToUint32:
1975 case IrOpcode::kTruncateFloat32ToInt32:
1976 case IrOpcode::kTruncateFloat32ToUint32:
1977 case IrOpcode::kTryTruncateFloat32ToInt64:
1978 case IrOpcode::kTryTruncateFloat64ToInt64:
1979 case IrOpcode::kTryTruncateFloat32ToUint64:
1980 case IrOpcode::kTryTruncateFloat64ToUint64:
1981 case IrOpcode::kTryTruncateFloat64ToInt32:
1982 case IrOpcode::kTryTruncateFloat64ToUint32:
1983 case IrOpcode::kFloat64ExtractLowWord32:
1984 case IrOpcode::kFloat64ExtractHighWord32:
1985 case IrOpcode::kFloat64InsertLowWord32:
1986 case IrOpcode::kFloat64InsertHighWord32:
1987 case IrOpcode::kWord32Select:
1988 case IrOpcode::kWord64Select:
1989 case IrOpcode::kFloat32Select:
1990 case IrOpcode::kFloat64Select:
1991 case IrOpcode::kInt32PairAdd:
1992 case IrOpcode::kInt32PairSub:
1993 case IrOpcode::kInt32PairMul:
1994 case IrOpcode::kWord32PairShl:
1995 case IrOpcode::kWord32PairShr:
1996 case IrOpcode::kWord32PairSar:
1997 case IrOpcode::kLoadStackCheckOffset:
1998 case IrOpcode::kLoadFramePointer:
1999 case IrOpcode::kLoadParentFramePointer:
2000 case IrOpcode::kLoadRootRegister:
2001 case IrOpcode::kUnalignedLoad:
2002 case IrOpcode::kUnalignedStore:
2003 case IrOpcode::kMemoryBarrier:
2004 case IrOpcode::kWord32AtomicLoad:
2005 case IrOpcode::kWord32AtomicStore:
2006 case IrOpcode::kWord32AtomicExchange:
2007 case IrOpcode::kWord32AtomicCompareExchange:
2008 case IrOpcode::kWord32AtomicAdd:
2009 case IrOpcode::kWord32AtomicSub:
2010 case IrOpcode::kWord32AtomicAnd:
2011 case IrOpcode::kWord32AtomicOr:
2012 case IrOpcode::kWord32AtomicXor:
2013 case IrOpcode::kWord64AtomicLoad:
2014 case IrOpcode::kWord64AtomicStore:
2015 case IrOpcode::kWord64AtomicAdd:
2016 case IrOpcode::kWord64AtomicSub:
2017 case IrOpcode::kWord64AtomicAnd:
2018 case IrOpcode::kWord64AtomicOr:
2019 case IrOpcode::kWord64AtomicXor:
2020 case IrOpcode::kWord64AtomicExchange:
2021 case IrOpcode::kWord64AtomicCompareExchange:
2022 case IrOpcode::kWord32AtomicPairLoad:
2023 case IrOpcode::kWord32AtomicPairStore:
2024 case IrOpcode::kWord32AtomicPairAdd:
2025 case IrOpcode::kWord32AtomicPairSub:
2026 case IrOpcode::kWord32AtomicPairAnd:
2027 case IrOpcode::kWord32AtomicPairOr:
2028 case IrOpcode::kWord32AtomicPairXor:
2029 case IrOpcode::kWord32AtomicPairExchange:
2030 case IrOpcode::kWord32AtomicPairCompareExchange:
2031 case IrOpcode::kSignExtendWord8ToInt32:
2032 case IrOpcode::kSignExtendWord16ToInt32:
2033 case IrOpcode::kSignExtendWord8ToInt64:
2034 case IrOpcode::kSignExtendWord16ToInt64:
2035 case IrOpcode::kSignExtendWord32ToInt64:
2036 case IrOpcode::kStaticAssert:
2037 case IrOpcode::kStackPointerGreaterThan:
2038 case IrOpcode::kTraceInstruction:
2039
2040#define SIMD_MACHINE_OP_CASE(Name) case IrOpcode::k##Name:
2043#undef SIMD_MACHINE_OP_CASE
2044
2045 // TODO(rossberg): Check.
2046 break;
2047 }
2048}
2049
2050void Verifier::Run(TFGraph* graph, Typing typing, CheckInputs check_inputs,
2051 CodeType code_type) {
2052 CHECK_NOT_NULL(graph->start());
2053 CHECK_NOT_NULL(graph->end());
2054 Zone zone(graph->zone()->allocator(), ZONE_NAME);
2055 Visitor visitor(&zone, typing, check_inputs, code_type);
2056 AllNodes all(&zone, graph);
2057 for (Node* node : all.reachable) visitor.Check(node, all);
2058
2059 // Check the uniqueness of projections.
2060 for (Node* proj : all.reachable) {
2061 if (proj->opcode() != IrOpcode::kProjection) continue;
2062 Node* node = proj->InputAt(0);
2063 for (Node* other : node->uses()) {
2064 if (all.IsLive(other) && other != proj &&
2065 other->opcode() == IrOpcode::kProjection &&
2066 other->InputAt(0) == node &&
2067 ProjectionIndexOf(other->op()) == ProjectionIndexOf(proj->op())) {
2068 FATAL("Node #%d:%s has duplicate projections #%d and #%d", node->id(),
2069 node->op()->mnemonic(), proj->id(), other->id());
2070 }
2071 }
2072 }
2073}
2074
2075// -----------------------------------------------------------------------------
2076
2078 BasicBlock* container, BasicBlock* use_block,
2079 int use_pos) {
2080 BasicBlock* block = use_block;
2081 while (true) {
2082 while (use_pos >= 0) {
2083 if (block->NodeAt(use_pos) == node) return true;
2084 use_pos--;
2085 }
2086 block = block->dominator();
2087 if (block == nullptr) break;
2088 use_pos = static_cast<int>(block->NodeCount()) - 1;
2089 if (node == block->control_input()) return true;
2090 }
2091 return false;
2092}
2093
2094
2095static bool Dominates(Schedule* schedule, Node* dominator, Node* dominatee) {
2096 BasicBlock* dom = schedule->block(dominator);
2097 BasicBlock* sub = schedule->block(dominatee);
2098 while (sub != nullptr) {
2099 if (sub == dom) {
2100 return true;
2101 }
2102 sub = sub->dominator();
2103 }
2104 return false;
2105}
2106
2107
2109 Node* node, int use_pos) {
2110 for (int j = node->op()->ValueInputCount() - 1; j >= 0; j--) {
2111 BasicBlock* use_block = block;
2112 if (node->opcode() == IrOpcode::kPhi) {
2113 use_block = use_block->PredecessorAt(j);
2114 use_pos = static_cast<int>(use_block->NodeCount()) - 1;
2115 }
2116 Node* input = node->InputAt(j);
2117 if (!HasDominatingDef(schedule, node->InputAt(j), block, use_block,
2118 use_pos)) {
2119 FATAL("Node #%d:%s in B%d is not dominated by input@%d #%d:%s",
2120 node->id(), node->op()->mnemonic(), block->rpo_number(), j,
2121 input->id(), input->op()->mnemonic());
2122 }
2123 }
2124 // Ensure that nodes are dominated by their control inputs;
2125 // kEnd is an exception, as unreachable blocks resulting from kMerge
2126 // are not in the RPO.
2127 if (node->op()->ControlInputCount() == 1 &&
2128 node->opcode() != IrOpcode::kEnd) {
2130 if (!Dominates(schedule, ctl, node)) {
2131 FATAL("Node #%d:%s in B%d is not dominated by control input #%d:%s",
2132 node->id(), node->op()->mnemonic(), block->rpo_number(), ctl->id(),
2133 ctl->op()->mnemonic());
2134 }
2135 }
2136}
2137
2138
2140 const size_t count = schedule->BasicBlockCount();
2141 Zone tmp_zone(schedule->zone()->allocator(), ZONE_NAME);
2142 Zone* zone = &tmp_zone;
2143 BasicBlock* start = schedule->start();
2144 BasicBlockVector* rpo_order = schedule->rpo_order();
2145
2146 // Verify the RPO order contains only blocks from this schedule.
2147 CHECK_GE(count, rpo_order->size());
2148 for (BasicBlockVector::iterator b = rpo_order->begin(); b != rpo_order->end();
2149 ++b) {
2150 CHECK_EQ((*b), schedule->GetBlockById((*b)->id()));
2151 // All predecessors and successors should be in rpo and in this schedule.
2152 for (BasicBlock const* predecessor : (*b)->predecessors()) {
2153 CHECK_GE(predecessor->rpo_number(), 0);
2154 CHECK_EQ(predecessor, schedule->GetBlockById(predecessor->id()));
2155 }
2156 for (BasicBlock const* successor : (*b)->successors()) {
2157 CHECK_GE(successor->rpo_number(), 0);
2158 CHECK_EQ(successor, schedule->GetBlockById(successor->id()));
2159 }
2160 }
2161
2162 // Verify RPO numbers of blocks.
2163 CHECK_EQ(start, rpo_order->at(0)); // Start should be first.
2164 for (size_t b = 0; b < rpo_order->size(); b++) {
2165 BasicBlock* block = rpo_order->at(b);
2166 CHECK_EQ(static_cast<int>(b), block->rpo_number());
2167 BasicBlock* dom = block->dominator();
2168 if (b == 0) {
2169 // All blocks except start should have a dominator.
2170 CHECK_NULL(dom);
2171 } else {
2172 // Check that the immediate dominator appears somewhere before the block.
2173 CHECK_NOT_NULL(dom);
2174 CHECK_LT(dom->rpo_number(), block->rpo_number());
2175 }
2176 }
2177
2178 // Verify that all blocks reachable from start are in the RPO.
2179 BitVector marked(static_cast<int>(count), zone);
2180 {
2181 ZoneQueue<BasicBlock*> queue(zone);
2182 queue.push(start);
2183 marked.Add(start->id().ToInt());
2184 while (!queue.empty()) {
2185 BasicBlock* block = queue.front();
2186 queue.pop();
2187 for (size_t s = 0; s < block->SuccessorCount(); s++) {
2188 BasicBlock* succ = block->SuccessorAt(s);
2189 if (!marked.Contains(succ->id().ToInt())) {
2190 marked.Add(succ->id().ToInt());
2191 queue.push(succ);
2192 }
2193 }
2194 }
2195 }
2196 // Verify marked blocks are in the RPO.
2197 for (int i = 0; i < static_cast<int>(count); i++) {
2198 BasicBlock* block = schedule->GetBlockById(BasicBlock::Id::FromInt(i));
2199 if (marked.Contains(i)) {
2200 CHECK_GE(block->rpo_number(), 0);
2201 CHECK_EQ(block, rpo_order->at(block->rpo_number()));
2202 }
2203 }
2204 // Verify RPO blocks are marked.
2205 for (size_t b = 0; b < rpo_order->size(); b++) {
2206 CHECK(marked.Contains(rpo_order->at(b)->id().ToInt()));
2207 }
2208
2209 {
2210 // Verify the dominance relation.
2211 ZoneVector<BitVector*> dominators(zone);
2212 dominators.resize(count, nullptr);
2213
2214 // Compute a set of all the nodes that dominate a given node by using
2215 // a forward fixpoint. O(n^2).
2216 ZoneQueue<BasicBlock*> queue(zone);
2217 queue.push(start);
2218 dominators[start->id().ToSize()] =
2219 zone->New<BitVector>(static_cast<int>(count), zone);
2220 while (!queue.empty()) {
2221 BasicBlock* block = queue.front();
2222 queue.pop();
2223 BitVector* block_doms = dominators[block->id().ToSize()];
2224 BasicBlock* idom = block->dominator();
2225 if (idom != nullptr && !block_doms->Contains(idom->id().ToInt())) {
2226 FATAL("Block B%d is not dominated by B%d", block->rpo_number(),
2227 idom->rpo_number());
2228 }
2229 for (size_t s = 0; s < block->SuccessorCount(); s++) {
2230 BasicBlock* succ = block->SuccessorAt(s);
2231 BitVector* succ_doms = dominators[succ->id().ToSize()];
2232
2233 if (succ_doms == nullptr) {
2234 // First time visiting the node. S.doms = B U B.doms
2235 succ_doms = zone->New<BitVector>(static_cast<int>(count), zone);
2236 succ_doms->CopyFrom(*block_doms);
2237 succ_doms->Add(block->id().ToInt());
2238 dominators[succ->id().ToSize()] = succ_doms;
2239 queue.push(succ);
2240 } else {
2241 // Nth time visiting the successor. S.doms = S.doms ^ (B U B.doms)
2242 bool had = succ_doms->Contains(block->id().ToInt());
2243 if (had) succ_doms->Remove(block->id().ToInt());
2244 if (succ_doms->IntersectIsChanged(*block_doms)) queue.push(succ);
2245 if (had) succ_doms->Add(block->id().ToInt());
2246 }
2247 }
2248 }
2249
2250 // Verify the immediateness of dominators.
2251 for (BasicBlockVector::iterator b = rpo_order->begin();
2252 b != rpo_order->end(); ++b) {
2253 BasicBlock* block = *b;
2254 BasicBlock* idom = block->dominator();
2255 if (idom == nullptr) continue;
2256 BitVector* block_doms = dominators[block->id().ToSize()];
2257
2258 for (int id : *block_doms) {
2259 BasicBlock* dom = schedule->GetBlockById(BasicBlock::Id::FromInt(id));
2260 if (dom != idom &&
2261 !dominators[idom->id().ToSize()]->Contains(dom->id().ToInt())) {
2262 FATAL("Block B%d is not immediately dominated by B%d",
2263 block->rpo_number(), idom->rpo_number());
2264 }
2265 }
2266 }
2267 }
2268
2269 // Verify phis are placed in the block of their control input.
2270 for (BasicBlockVector::iterator b = rpo_order->begin(); b != rpo_order->end();
2271 ++b) {
2272 for (BasicBlock::const_iterator i = (*b)->begin(); i != (*b)->end(); ++i) {
2273 Node* phi = *i;
2274 if (phi->opcode() != IrOpcode::kPhi) continue;
2275 // TODO(titzer): Nasty special case. Phis from RawMachineAssembler
2276 // schedules don't have control inputs.
2277 if (phi->InputCount() > phi->op()->ValueInputCount()) {
2278 Node* control = NodeProperties::GetControlInput(phi);
2279 CHECK(control->opcode() == IrOpcode::kMerge ||
2280 control->opcode() == IrOpcode::kLoop);
2281 CHECK_EQ((*b), schedule->block(control));
2282 }
2283 }
2284 }
2285
2286 // Verify that all uses are dominated by their definitions.
2287 for (BasicBlockVector::iterator b = rpo_order->begin(); b != rpo_order->end();
2288 ++b) {
2289 BasicBlock* block = *b;
2290
2291 // Check inputs to control for this block.
2292 Node* control = block->control_input();
2293 if (control != nullptr) {
2294 CHECK_EQ(block, schedule->block(control));
2295 CheckInputsDominate(schedule, block, control,
2296 static_cast<int>(block->NodeCount()) - 1);
2297 }
2298 // Check inputs for all nodes in the block.
2299 for (size_t i = 0; i < block->NodeCount(); i++) {
2300 Node* node = block->NodeAt(i);
2301 CheckInputsDominate(schedule, block, node, static_cast<int>(i) - 1);
2302 }
2303 }
2304}
2305
2306
2307#ifdef DEBUG
2308
2309// static
2310void Verifier::VerifyNode(Node* node) {
2312 node->InputCount()) {
2313 v8::base::OS::PrintError("#\n# Verification failure for node:\n#\n");
2314 node->Print(std::cerr);
2315 }
2317 node->InputCount());
2318 // If this node has no effect or no control outputs,
2319 // we check that none of its uses are effect or control inputs.
2320 bool check_no_control = node->op()->ControlOutputCount() == 0;
2321 bool check_no_effect = node->op()->EffectOutputCount() == 0;
2322 bool check_no_frame_state = node->opcode() != IrOpcode::kFrameState;
2323 if (check_no_effect || check_no_control) {
2324 for (Edge edge : node->use_edges()) {
2325 Node* const user = edge.from();
2326 DCHECK(!user->IsDead() || FailSoon(node));
2328 DCHECK(!check_no_control || FailSoon(node));
2329 } else if (NodeProperties::IsEffectEdge(edge)) {
2330 DCHECK(!check_no_effect || FailSoon(node));
2331 } else if (NodeProperties::IsFrameStateEdge(edge)) {
2332 DCHECK(!check_no_frame_state || FailSoon(node));
2333 }
2334 }
2335 }
2336
2337 // Frame state input should be a frame state (or sentinel).
2338 if (OperatorProperties::GetFrameStateInputCount(node->op()) > 0) {
2339 Node* input = NodeProperties::GetFrameStateInput(node);
2340 DCHECK(input->opcode() == IrOpcode::kFrameState ||
2341 input->opcode() == IrOpcode::kStart ||
2342 input->opcode() == IrOpcode::kDead ||
2343 input->opcode() == IrOpcode::kDeadValue || FailSoon(node));
2344 }
2345 // Effect inputs should be effect-producing nodes (or sentinels).
2346 for (int i = 0; i < node->op()->EffectInputCount(); i++) {
2347 Node* input = NodeProperties::GetEffectInput(node, i);
2348 DCHECK(input->op()->EffectOutputCount() > 0 ||
2349 input->opcode() == IrOpcode::kDead || FailSoon(node));
2350 }
2351 // Control inputs should be control-producing nodes (or sentinels).
2352 for (int i = 0; i < node->op()->ControlInputCount(); i++) {
2353 Node* input = NodeProperties::GetControlInput(node, i);
2354 DCHECK(input->op()->ControlOutputCount() > 0 ||
2355 input->opcode() == IrOpcode::kDead || FailSoon(node));
2356 }
2357}
2358
2359
2360void Verifier::VerifyEdgeInputReplacement(const Edge& edge,
2361 const Node* replacement) {
2362 // Check that the user does not misuse the replacement.
2364 replacement->op()->ControlOutputCount() > 0);
2366 replacement->op()->EffectOutputCount() > 0);
2368 replacement->opcode() == IrOpcode::kFrameState ||
2369 replacement->opcode() == IrOpcode::kDead ||
2370 replacement->opcode() == IrOpcode::kDeadValue);
2371}
2372
2373#endif // DEBUG
2374
2375} // namespace compiler
2376} // namespace internal
2377} // namespace v8
Schedule * schedule
Builtins::Kind kind
Definition builtins.cc:40
bool IntersectIsChanged(const BitVector &other)
Definition bit-vector.h:227
void CopyFrom(const BitVector &other)
Definition bit-vector.h:155
bool Contains(int i) const
Definition bit-vector.h:180
static constexpr int kMaxLength
void resize(size_t new_size)
T * New(Args &&... args)
Definition zone.h:114
BasicBlock * SuccessorAt(size_t index)
Definition schedule.h:85
NodeVector::const_iterator const_iterator
Definition schedule.h:105
BasicBlock * dominator() const
Definition schedule.h:138
BasicBlock * PredecessorAt(size_t index)
Definition schedule.h:76
BasicBlockVector & successors()
Definition schedule.h:82
BasicBlockVector & predecessors()
Definition schedule.h:73
FeedbackSource const & feedback() const
static bool IsGraphTerminator(Value value)
Definition opcodes.h:1415
static Type GetType(const Node *node)
static bool IsTyped(const Node *node)
static Node * GetEffectInput(Node *node, int index=0)
static Node * GetContextInput(Node *node)
static Node * GetFrameStateInput(Node *node)
static Node * GetValueInput(Node *node, int index)
static Node * GetControlInput(Node *node, int index=0)
constexpr IrOpcode::Value opcode() const
Definition node.h:52
Inputs inputs() const
Definition node.h:478
const Operator * op() const
Definition node.h:50
Node * InputAt(int index) const
Definition node.h:70
NodeId id() const
Definition node.h:57
static int GetTotalInputCount(const Operator *op)
static int GetContextInputCount(const Operator *op)
static int GetFrameStateInputCount(const Operator *op)
FeedbackSource const & feedback() const
static void Run(Schedule *schedule)
Definition verifier.cc:2139
static TypeCache const * Get()
static Type Union(Type type1, Type type2, Zone *zone)
static Type Range(double min, double max, Zone *zone)
Visitor(Zone *z, Typing typed, CheckInputs check_inputs, CodeType code_type)
Definition verifier.cc:34
void Check(Node *node, const AllNodes &all)
Definition verifier.cc:148
void CheckTypeMaybe(Node *node, Type type)
Definition verifier.cc:68
void CheckOutput(Node *node, Node *use, int count, const char *kind)
Definition verifier.cc:87
void CheckTypeIs(Node *node, Type type)
Definition verifier.cc:60
void CheckValueInputIs(Node *node, int i, Type type)
Definition verifier.cc:76
void CheckSwitch(Node *node, const AllNodes &all)
Definition verifier.cc:98
static void VerifyEdgeInputReplacement(const Edge &edge, const Node *replacement)
Definition verifier.h:52
static void VerifyNode(Node *node)
Definition verifier.h:51
static void Run(TFGraph *graph, Typing typing=TYPED, CheckInputs check_inputs=kAll, CodeType code_type=kDefault)
Definition verifier.cc:2050
int start
uint32_t count
RpoNumber block
const BranchParameters & BranchParametersOf(const Operator *const op)
IfValueParameters const & IfValueParametersOf(const Operator *op)
size_t ProjectionIndexOf(const Operator *const op)
const StoreGlobalParameters & StoreGlobalParametersOf(const Operator *op)
DefineNamedOwnPropertyParameters const & DefineNamedOwnPropertyParametersOf(const Operator *op)
int ParameterIndexOf(const Operator *const op)
static bool HasDominatingDef(Schedule *schedule, Node *node, BasicBlock *container, BasicBlock *use_block, int use_pos)
Definition verifier.cc:2077
Type TypeGuardTypeOf(Operator const *op)
SelectParameters const & SelectParametersOf(const Operator *const op)
const LoadGlobalParameters & LoadGlobalParametersOf(const Operator *op)
FeedbackParameter const & FeedbackParameterOf(const Operator *op)
static bool Dominates(Schedule *schedule, Node *dominator, Node *dominatee)
Definition verifier.cc:2095
static void CheckInputsDominate(Schedule *schedule, BasicBlock *block, Node *node, int use_pos)
Definition verifier.cc:2108
PropertyAccess const & PropertyAccessOf(const Operator *op)
constexpr double kMaxSafeInteger
Definition globals.h:1985
bool Is(IndirectHandle< U > value)
Definition handles-inl.h:51
V8_EXPORT_PRIVATE FlagValues v8_flags
#define MACHINE_SIMD256_OP_LIST(V)
Definition opcodes.h:1159
#define SIMPLIFIED_BIGINT_BINOP_LIST(V)
Definition opcodes.h:367
#define MACHINE_SIMD128_OP_LIST(V)
Definition opcodes.h:879
#define SIMPLIFIED_SPECULATIVE_BIGINT_BINOP_LIST(V)
Definition opcodes.h:561
#define SPECULATIVE_BIGINT_BINOP(Name)
#define BIGINT_BINOP(Name)
#define FATAL(...)
Definition logging.h:47
#define CHECK_GE(lhs, rhs)
#define CHECK(condition)
Definition logging.h:124
#define CHECK_GT(lhs, rhs)
#define CHECK_LT(lhs, rhs)
#define CHECK_LE(lhs, rhs)
#define CHECK_NULL(val)
#define CHECK_NOT_NULL(val)
#define CHECK_NE(lhs, rhs)
#define CHECK_EQ(lhs, rhs)
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_EQ(v1, v2)
Definition logging.h:485
#define DCHECK_GT(v1, v2)
Definition logging.h:487
#define IF_WASM(V,...)
Definition macros.h:472
#define SIMD_MACHINE_OP_CASE(Name)
wasm::ValueType type
#define ZONE_NAME
Definition zone.h:22