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