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