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/bit-vector.h"
14 #include "src/compiler/all-nodes.h"
15 #include "src/compiler/common-operator.h"
16 #include "src/compiler/graph.h"
17 #include "src/compiler/js-operator.h"
18 #include "src/compiler/node-properties.h"
19 #include "src/compiler/node.h"
20 #include "src/compiler/opcodes.h"
21 #include "src/compiler/operator-properties.h"
22 #include "src/compiler/operator.h"
23 #include "src/compiler/schedule.h"
24 #include "src/compiler/simplified-operator.h"
25 #include "src/ostreams.h"
26
27 namespace v8 {
28 namespace internal {
29 namespace compiler {
30
31
32 class Verifier::Visitor {
33 public:
Visitor(Zone * z,Typing typed,CheckInputs check_inputs)34 Visitor(Zone* z, Typing typed, CheckInputs check_inputs)
35 : zone(z), typing(typed), check_inputs(check_inputs) {}
36
37 void Check(Node* node);
38
39 Zone* zone;
40 Typing typing;
41 CheckInputs check_inputs;
42
43 private:
CheckNotTyped(Node * node)44 void CheckNotTyped(Node* node) {
45 if (NodeProperties::IsTyped(node)) {
46 std::ostringstream str;
47 str << "TypeError: node #" << node->id() << ":" << *node->op()
48 << " should never have a type";
49 FATAL(str.str().c_str());
50 }
51 }
CheckTypeIs(Node * node,Type * type)52 void CheckTypeIs(Node* node, Type* type) {
53 if (typing == TYPED && !NodeProperties::GetType(node)->Is(type)) {
54 std::ostringstream str;
55 str << "TypeError: node #" << node->id() << ":" << *node->op()
56 << " type ";
57 NodeProperties::GetType(node)->PrintTo(str);
58 str << " is not ";
59 type->PrintTo(str);
60 FATAL(str.str().c_str());
61 }
62 }
CheckTypeMaybe(Node * node,Type * type)63 void CheckTypeMaybe(Node* node, Type* type) {
64 if (typing == TYPED && !NodeProperties::GetType(node)->Maybe(type)) {
65 std::ostringstream str;
66 str << "TypeError: node #" << node->id() << ":" << *node->op()
67 << " type ";
68 NodeProperties::GetType(node)->PrintTo(str);
69 str << " must intersect ";
70 type->PrintTo(str);
71 FATAL(str.str().c_str());
72 }
73 }
CheckValueInputIs(Node * node,int i,Type * type)74 void CheckValueInputIs(Node* node, int i, Type* type) {
75 Node* input = NodeProperties::GetValueInput(node, i);
76 if (typing == TYPED && !NodeProperties::GetType(input)->Is(type)) {
77 std::ostringstream str;
78 str << "TypeError: node #" << node->id() << ":" << *node->op()
79 << "(input @" << i << " = " << input->opcode() << ":"
80 << input->op()->mnemonic() << ") type ";
81 NodeProperties::GetType(input)->PrintTo(str);
82 str << " is not ";
83 type->PrintTo(str);
84 FATAL(str.str().c_str());
85 }
86 }
CheckOutput(Node * node,Node * use,int count,const char * kind)87 void CheckOutput(Node* node, Node* use, int count, const char* kind) {
88 if (count <= 0) {
89 std::ostringstream str;
90 str << "GraphError: node #" << node->id() << ":" << *node->op()
91 << " does not produce " << kind << " output used by node #"
92 << use->id() << ":" << *use->op();
93 FATAL(str.str().c_str());
94 }
95 }
96 };
97
98
Check(Node * node)99 void Verifier::Visitor::Check(Node* node) {
100 int value_count = node->op()->ValueInputCount();
101 int context_count = OperatorProperties::GetContextInputCount(node->op());
102 int frame_state_count =
103 OperatorProperties::GetFrameStateInputCount(node->op());
104 int effect_count = node->op()->EffectInputCount();
105 int control_count = node->op()->ControlInputCount();
106
107 // Verify number of inputs matches up.
108 int input_count = value_count + context_count + frame_state_count;
109 if (check_inputs == kAll) {
110 input_count += effect_count + control_count;
111 }
112 CHECK_EQ(input_count, node->InputCount());
113
114 // Verify that frame state has been inserted for the nodes that need it.
115 for (int i = 0; i < frame_state_count; i++) {
116 Node* frame_state = NodeProperties::GetFrameStateInput(node);
117 CHECK(frame_state->opcode() == IrOpcode::kFrameState ||
118 // kFrameState uses Start as a sentinel.
119 (node->opcode() == IrOpcode::kFrameState &&
120 frame_state->opcode() == IrOpcode::kStart));
121 }
122
123 // Verify all value inputs actually produce a value.
124 for (int i = 0; i < value_count; ++i) {
125 Node* value = NodeProperties::GetValueInput(node, i);
126 CheckOutput(value, node, value->op()->ValueOutputCount(), "value");
127 // Verify that only parameters and projections can have input nodes with
128 // multiple outputs.
129 CHECK(node->opcode() == IrOpcode::kParameter ||
130 node->opcode() == IrOpcode::kProjection ||
131 value->op()->ValueOutputCount() <= 1);
132 }
133
134 // Verify all context inputs are value nodes.
135 for (int i = 0; i < context_count; ++i) {
136 Node* context = NodeProperties::GetContextInput(node);
137 CheckOutput(context, node, context->op()->ValueOutputCount(), "context");
138 }
139
140 if (check_inputs == kAll) {
141 // Verify all effect inputs actually have an effect.
142 for (int i = 0; i < effect_count; ++i) {
143 Node* effect = NodeProperties::GetEffectInput(node);
144 CheckOutput(effect, node, effect->op()->EffectOutputCount(), "effect");
145 }
146
147 // Verify all control inputs are control nodes.
148 for (int i = 0; i < control_count; ++i) {
149 Node* control = NodeProperties::GetControlInput(node, i);
150 CheckOutput(control, node, control->op()->ControlOutputCount(),
151 "control");
152 }
153
154 // Verify that nodes that can throw only have IfSuccess/IfException control
155 // uses.
156 if (!node->op()->HasProperty(Operator::kNoThrow)) {
157 int count_success = 0, count_exception = 0;
158 for (Edge edge : node->use_edges()) {
159 if (!NodeProperties::IsControlEdge(edge)) {
160 continue;
161 }
162 Node* control_use = edge.from();
163 if (control_use->opcode() != IrOpcode::kIfSuccess &&
164 control_use->opcode() != IrOpcode::kIfException) {
165 V8_Fatal(__FILE__, __LINE__,
166 "#%d:%s should be followed by IfSuccess/IfException, but is "
167 "followed by #%d:%s",
168 node->id(), node->op()->mnemonic(), control_use->id(),
169 control_use->op()->mnemonic());
170 }
171 if (control_use->opcode() == IrOpcode::kIfSuccess) ++count_success;
172 if (control_use->opcode() == IrOpcode::kIfException) ++count_exception;
173 CHECK_LE(count_success, 1);
174 CHECK_LE(count_exception, 1);
175 }
176 }
177 }
178
179 switch (node->opcode()) {
180 case IrOpcode::kStart:
181 // Start has no inputs.
182 CHECK_EQ(0, input_count);
183 // Type is a tuple.
184 // TODO(rossberg): Multiple outputs are currently typed as Internal.
185 CheckTypeIs(node, Type::Internal());
186 break;
187 case IrOpcode::kEnd:
188 // End has no outputs.
189 CHECK(node->op()->ValueOutputCount() == 0);
190 CHECK(node->op()->EffectOutputCount() == 0);
191 CHECK(node->op()->ControlOutputCount() == 0);
192 // Type is empty.
193 CheckNotTyped(node);
194 break;
195 case IrOpcode::kDead:
196 // Dead is never connected to the graph.
197 UNREACHABLE();
198 break;
199 case IrOpcode::kBranch: {
200 // Branch uses are IfTrue and IfFalse.
201 int count_true = 0, count_false = 0;
202 for (const Node* use : node->uses()) {
203 CHECK(use->opcode() == IrOpcode::kIfTrue ||
204 use->opcode() == IrOpcode::kIfFalse);
205 if (use->opcode() == IrOpcode::kIfTrue) ++count_true;
206 if (use->opcode() == IrOpcode::kIfFalse) ++count_false;
207 }
208 CHECK_EQ(1, count_true);
209 CHECK_EQ(1, count_false);
210 // The condition must be a Boolean.
211 CheckValueInputIs(node, 0, Type::Boolean());
212 // Type is empty.
213 CheckNotTyped(node);
214 break;
215 }
216 case IrOpcode::kIfTrue:
217 case IrOpcode::kIfFalse:
218 CHECK_EQ(IrOpcode::kBranch,
219 NodeProperties::GetControlInput(node, 0)->opcode());
220 // Type is empty.
221 CheckNotTyped(node);
222 break;
223 case IrOpcode::kIfSuccess: {
224 // IfSuccess and IfException continuation only on throwing nodes.
225 Node* input = NodeProperties::GetControlInput(node, 0);
226 CHECK(!input->op()->HasProperty(Operator::kNoThrow));
227 // Type is empty.
228 CheckNotTyped(node);
229 break;
230 }
231 case IrOpcode::kIfException: {
232 // IfSuccess and IfException continuation only on throwing nodes.
233 Node* input = NodeProperties::GetControlInput(node, 0);
234 CHECK(!input->op()->HasProperty(Operator::kNoThrow));
235 // Type can be anything.
236 CheckTypeIs(node, Type::Any());
237 break;
238 }
239 case IrOpcode::kSwitch: {
240 // Switch uses are Case and Default.
241 int count_case = 0, count_default = 0;
242 for (const Node* use : node->uses()) {
243 switch (use->opcode()) {
244 case IrOpcode::kIfValue: {
245 for (const Node* user : node->uses()) {
246 if (user != use && user->opcode() == IrOpcode::kIfValue) {
247 CHECK_NE(OpParameter<int32_t>(use->op()),
248 OpParameter<int32_t>(user->op()));
249 }
250 }
251 ++count_case;
252 break;
253 }
254 case IrOpcode::kIfDefault: {
255 ++count_default;
256 break;
257 }
258 default: {
259 V8_Fatal(__FILE__, __LINE__, "Switch #%d illegally used by #%d:%s",
260 node->id(), use->id(), use->op()->mnemonic());
261 break;
262 }
263 }
264 }
265 CHECK_EQ(1, count_default);
266 CHECK_EQ(node->op()->ControlOutputCount(), count_case + count_default);
267 // Type is empty.
268 CheckNotTyped(node);
269 break;
270 }
271 case IrOpcode::kIfValue:
272 case IrOpcode::kIfDefault:
273 CHECK_EQ(IrOpcode::kSwitch,
274 NodeProperties::GetControlInput(node)->opcode());
275 // Type is empty.
276 CheckNotTyped(node);
277 break;
278 case IrOpcode::kLoop:
279 case IrOpcode::kMerge:
280 CHECK_EQ(control_count, input_count);
281 // Type is empty.
282 CheckNotTyped(node);
283 break;
284 case IrOpcode::kDeoptimizeIf:
285 case IrOpcode::kDeoptimizeUnless:
286 // Type is empty.
287 CheckNotTyped(node);
288 break;
289 case IrOpcode::kTrapIf:
290 case IrOpcode::kTrapUnless:
291 // Type is empty.
292 CheckNotTyped(node);
293 break;
294 case IrOpcode::kDeoptimize:
295 case IrOpcode::kReturn:
296 case IrOpcode::kThrow:
297 // Deoptimize, Return and Throw uses are End.
298 for (const Node* use : node->uses()) {
299 CHECK_EQ(IrOpcode::kEnd, use->opcode());
300 }
301 // Type is empty.
302 CheckNotTyped(node);
303 break;
304 case IrOpcode::kTerminate:
305 // Terminates take one loop and effect.
306 CHECK_EQ(1, control_count);
307 CHECK_EQ(1, effect_count);
308 CHECK_EQ(2, input_count);
309 CHECK_EQ(IrOpcode::kLoop,
310 NodeProperties::GetControlInput(node)->opcode());
311 // Terminate uses are End.
312 for (const Node* use : node->uses()) {
313 CHECK_EQ(IrOpcode::kEnd, use->opcode());
314 }
315 // Type is empty.
316 CheckNotTyped(node);
317 break;
318 case IrOpcode::kOsrNormalEntry:
319 case IrOpcode::kOsrLoopEntry:
320 // Osr entries take one control and effect.
321 CHECK_EQ(1, control_count);
322 CHECK_EQ(1, effect_count);
323 CHECK_EQ(2, input_count);
324 // Type is empty.
325 CheckNotTyped(node);
326 break;
327
328 // Common operators
329 // ----------------
330 case IrOpcode::kParameter: {
331 // Parameters have the start node as inputs.
332 CHECK_EQ(1, input_count);
333 // Parameter has an input that produces enough values.
334 int const index = ParameterIndexOf(node->op());
335 Node* const start = NodeProperties::GetValueInput(node, 0);
336 CHECK_EQ(IrOpcode::kStart, start->opcode());
337 // Currently, parameter indices start at -1 instead of 0.
338 CHECK_LE(-1, index);
339 CHECK_LT(index + 1, start->op()->ValueOutputCount());
340 // Type can be anything.
341 CheckTypeIs(node, Type::Any());
342 break;
343 }
344 case IrOpcode::kInt32Constant: // TODO(turbofan): rename Word32Constant?
345 case IrOpcode::kInt64Constant: // TODO(turbofan): rename Word64Constant?
346 case IrOpcode::kFloat32Constant:
347 case IrOpcode::kFloat64Constant:
348 case IrOpcode::kRelocatableInt32Constant:
349 case IrOpcode::kRelocatableInt64Constant:
350 // Constants have no inputs.
351 CHECK_EQ(0, input_count);
352 // Type is empty.
353 CheckNotTyped(node);
354 break;
355 case IrOpcode::kNumberConstant:
356 // Constants have no inputs.
357 CHECK_EQ(0, input_count);
358 // Type is a number.
359 CheckTypeIs(node, Type::Number());
360 break;
361 case IrOpcode::kHeapConstant:
362 // Constants have no inputs.
363 CHECK_EQ(0, input_count);
364 // Type is anything.
365 CheckTypeIs(node, Type::Any());
366 break;
367 case IrOpcode::kExternalConstant:
368 case IrOpcode::kPointerConstant:
369 // Constants have no inputs.
370 CHECK_EQ(0, input_count);
371 // Type is an external pointer.
372 CheckTypeIs(node, Type::ExternalPointer());
373 break;
374 case IrOpcode::kOsrValue:
375 // OSR values have a value and a control input.
376 CHECK_EQ(1, control_count);
377 CHECK_EQ(1, input_count);
378 // Type is merged from other values in the graph and could be any.
379 CheckTypeIs(node, Type::Any());
380 break;
381 case IrOpcode::kOsrGuard:
382 // OSR values have a value and a control input.
383 CHECK_EQ(1, value_count);
384 CHECK_EQ(1, effect_count);
385 CHECK_EQ(1, control_count);
386 switch (OsrGuardTypeOf(node->op())) {
387 case OsrGuardType::kUninitialized:
388 CheckTypeIs(node, Type::None());
389 break;
390 case OsrGuardType::kSignedSmall:
391 CheckTypeIs(node, Type::SignedSmall());
392 break;
393 case OsrGuardType::kAny:
394 CheckTypeIs(node, Type::Any());
395 break;
396 }
397 break;
398 case IrOpcode::kProjection: {
399 // Projection has an input that produces enough values.
400 int index = static_cast<int>(ProjectionIndexOf(node->op()));
401 Node* input = NodeProperties::GetValueInput(node, 0);
402 CHECK_GT(input->op()->ValueOutputCount(), index);
403 // Type can be anything.
404 // TODO(rossberg): Introduce tuple types for this.
405 // TODO(titzer): Convince rossberg not to.
406 CheckTypeIs(node, Type::Any());
407 break;
408 }
409 case IrOpcode::kSelect: {
410 CHECK_EQ(0, effect_count);
411 CHECK_EQ(0, control_count);
412 CHECK_EQ(3, value_count);
413 // The condition must be a Boolean.
414 CheckValueInputIs(node, 0, Type::Boolean());
415 // Type can be anything.
416 CheckTypeIs(node, Type::Any());
417 break;
418 }
419 case IrOpcode::kPhi: {
420 // Phi input count matches parent control node.
421 CHECK_EQ(0, effect_count);
422 CHECK_EQ(1, control_count);
423 Node* control = NodeProperties::GetControlInput(node, 0);
424 CHECK_EQ(value_count, control->op()->ControlInputCount());
425 CHECK_EQ(input_count, 1 + value_count);
426 // Type must be subsumed by all input types.
427 // TODO(rossberg): for now at least, narrowing does not really hold.
428 /*
429 for (int i = 0; i < value_count; ++i) {
430 CHECK(type_of(ValueInput(node, i))->Is(type_of(node)));
431 }
432 */
433 break;
434 }
435 case IrOpcode::kInductionVariablePhi: {
436 // This is only a temporary node for the typer.
437 UNREACHABLE();
438 break;
439 }
440 case IrOpcode::kEffectPhi: {
441 // EffectPhi input count matches parent control node.
442 CHECK_EQ(0, value_count);
443 CHECK_EQ(1, control_count);
444 Node* control = NodeProperties::GetControlInput(node, 0);
445 CHECK_EQ(effect_count, control->op()->ControlInputCount());
446 CHECK_EQ(input_count, 1 + effect_count);
447 break;
448 }
449 case IrOpcode::kLoopExit: {
450 CHECK_EQ(2, control_count);
451 Node* loop = NodeProperties::GetControlInput(node, 1);
452 CHECK_EQ(IrOpcode::kLoop, loop->opcode());
453 break;
454 }
455 case IrOpcode::kLoopExitValue: {
456 CHECK_EQ(1, control_count);
457 Node* loop_exit = NodeProperties::GetControlInput(node, 0);
458 CHECK_EQ(IrOpcode::kLoopExit, loop_exit->opcode());
459 break;
460 }
461 case IrOpcode::kLoopExitEffect: {
462 CHECK_EQ(1, control_count);
463 Node* loop_exit = NodeProperties::GetControlInput(node, 0);
464 CHECK_EQ(IrOpcode::kLoopExit, loop_exit->opcode());
465 break;
466 }
467 case IrOpcode::kCheckpoint:
468 // Type is empty.
469 CheckNotTyped(node);
470 break;
471 case IrOpcode::kBeginRegion:
472 // TODO(rossberg): what are the constraints on these?
473 break;
474 case IrOpcode::kFinishRegion: {
475 // TODO(rossberg): what are the constraints on these?
476 // Type must be subsumed by input type.
477 if (typing == TYPED) {
478 Node* val = NodeProperties::GetValueInput(node, 0);
479 CHECK(NodeProperties::GetType(val)->Is(NodeProperties::GetType(node)));
480 }
481 break;
482 }
483 case IrOpcode::kFrameState: {
484 // TODO(jarin): what are the constraints on these?
485 CHECK_EQ(5, value_count);
486 CHECK_EQ(0, control_count);
487 CHECK_EQ(0, effect_count);
488 CHECK_EQ(6, input_count);
489 for (int i = 0; i < 3; ++i) {
490 CHECK(NodeProperties::GetValueInput(node, i)->opcode() ==
491 IrOpcode::kStateValues ||
492 NodeProperties::GetValueInput(node, i)->opcode() ==
493 IrOpcode::kTypedStateValues);
494 }
495 break;
496 }
497 case IrOpcode::kStateValues:
498 case IrOpcode::kTypedStateValues:
499 case IrOpcode::kArgumentsObjectState:
500 case IrOpcode::kObjectState:
501 case IrOpcode::kTypedObjectState:
502 // TODO(jarin): what are the constraints on these?
503 break;
504 case IrOpcode::kCall:
505 // TODO(rossberg): what are the constraints on these?
506 break;
507 case IrOpcode::kTailCall:
508 // TODO(bmeurer): what are the constraints on these?
509 break;
510
511 // JavaScript operators
512 // --------------------
513 case IrOpcode::kJSEqual:
514 case IrOpcode::kJSNotEqual:
515 case IrOpcode::kJSStrictEqual:
516 case IrOpcode::kJSStrictNotEqual:
517 case IrOpcode::kJSLessThan:
518 case IrOpcode::kJSGreaterThan:
519 case IrOpcode::kJSLessThanOrEqual:
520 case IrOpcode::kJSGreaterThanOrEqual:
521 // Type is Boolean.
522 CheckTypeIs(node, Type::Boolean());
523 break;
524
525 case IrOpcode::kJSBitwiseOr:
526 case IrOpcode::kJSBitwiseXor:
527 case IrOpcode::kJSBitwiseAnd:
528 case IrOpcode::kJSShiftLeft:
529 case IrOpcode::kJSShiftRight:
530 case IrOpcode::kJSShiftRightLogical:
531 // Type is 32 bit integral.
532 CheckTypeIs(node, Type::Integral32());
533 break;
534 case IrOpcode::kJSAdd:
535 // Type is Number or String.
536 CheckTypeIs(node, Type::NumberOrString());
537 break;
538 case IrOpcode::kJSSubtract:
539 case IrOpcode::kJSMultiply:
540 case IrOpcode::kJSDivide:
541 case IrOpcode::kJSModulus:
542 // Type is Number.
543 CheckTypeIs(node, Type::Number());
544 break;
545
546 case IrOpcode::kJSToBoolean:
547 // Type is Boolean.
548 CheckTypeIs(node, Type::Boolean());
549 break;
550 case IrOpcode::kJSToInteger:
551 // Type is OrderedNumber.
552 CheckTypeIs(node, Type::OrderedNumber());
553 break;
554 case IrOpcode::kJSToLength:
555 // Type is OrderedNumber.
556 CheckTypeIs(node, Type::OrderedNumber());
557 break;
558 case IrOpcode::kJSToName:
559 // Type is Name.
560 CheckTypeIs(node, Type::Name());
561 break;
562 case IrOpcode::kJSToNumber:
563 // Type is Number.
564 CheckTypeIs(node, Type::Number());
565 break;
566 case IrOpcode::kJSToString:
567 // Type is String.
568 CheckTypeIs(node, Type::String());
569 break;
570 case IrOpcode::kJSToObject:
571 // Type is Receiver.
572 CheckTypeIs(node, Type::Receiver());
573 break;
574
575 case IrOpcode::kJSCreate:
576 // Type is Object.
577 CheckTypeIs(node, Type::Object());
578 break;
579 case IrOpcode::kJSCreateArguments:
580 // Type is OtherObject.
581 CheckTypeIs(node, Type::OtherObject());
582 break;
583 case IrOpcode::kJSCreateArray:
584 // Type is OtherObject.
585 CheckTypeIs(node, Type::OtherObject());
586 break;
587 case IrOpcode::kJSCreateClosure:
588 // Type is Function.
589 CheckTypeIs(node, Type::Function());
590 break;
591 case IrOpcode::kJSCreateIterResultObject:
592 // Type is OtherObject.
593 CheckTypeIs(node, Type::OtherObject());
594 break;
595 case IrOpcode::kJSCreateKeyValueArray:
596 // Type is OtherObject.
597 CheckTypeIs(node, Type::OtherObject());
598 break;
599 case IrOpcode::kJSCreateLiteralArray:
600 case IrOpcode::kJSCreateLiteralObject:
601 case IrOpcode::kJSCreateLiteralRegExp:
602 // Type is OtherObject.
603 CheckTypeIs(node, Type::OtherObject());
604 break;
605 case IrOpcode::kJSLoadProperty:
606 // Type can be anything.
607 CheckTypeIs(node, Type::Any());
608 CHECK(PropertyAccessOf(node->op()).feedback().IsValid());
609 break;
610 case IrOpcode::kJSLoadNamed:
611 // Type can be anything.
612 CheckTypeIs(node, Type::Any());
613 CHECK(NamedAccessOf(node->op()).feedback().IsValid());
614 break;
615 case IrOpcode::kJSLoadGlobal:
616 // Type can be anything.
617 CheckTypeIs(node, Type::Any());
618 CHECK(LoadGlobalParametersOf(node->op()).feedback().IsValid());
619 break;
620 case IrOpcode::kJSStoreProperty:
621 // Type is empty.
622 CheckNotTyped(node);
623 CHECK(PropertyAccessOf(node->op()).feedback().IsValid());
624 break;
625 case IrOpcode::kJSStoreNamed:
626 // Type is empty.
627 CheckNotTyped(node);
628 CHECK(NamedAccessOf(node->op()).feedback().IsValid());
629 break;
630 case IrOpcode::kJSStoreGlobal:
631 // Type is empty.
632 CheckNotTyped(node);
633 CHECK(StoreGlobalParametersOf(node->op()).feedback().IsValid());
634 break;
635 case IrOpcode::kJSStoreNamedOwn:
636 // Type is empty.
637 CheckNotTyped(node);
638 CHECK(StoreNamedOwnParametersOf(node->op()).feedback().IsValid());
639 break;
640 case IrOpcode::kJSStoreDataPropertyInLiteral:
641 // Type is empty.
642 CheckNotTyped(node);
643 break;
644 case IrOpcode::kJSDeleteProperty:
645 case IrOpcode::kJSHasProperty:
646 case IrOpcode::kJSInstanceOf:
647 case IrOpcode::kJSOrdinaryHasInstance:
648 // Type is Boolean.
649 CheckTypeIs(node, Type::Boolean());
650 break;
651 case IrOpcode::kJSClassOf:
652 // Type is InternaliedString \/ Null.
653 CheckTypeIs(node, Type::InternalizedStringOrNull());
654 break;
655 case IrOpcode::kJSTypeOf:
656 // Type is InternalizedString.
657 CheckTypeIs(node, Type::InternalizedString());
658 break;
659 case IrOpcode::kJSGetSuperConstructor:
660 // We don't check the input for Type::Function because
661 // this_function can be context-allocated.
662 // Any -> Callable.
663 CheckValueInputIs(node, 0, Type::Any());
664 CheckTypeIs(node, Type::Callable());
665 break;
666
667 case IrOpcode::kJSLoadContext:
668 // Type can be anything.
669 CheckTypeIs(node, Type::Any());
670 break;
671 case IrOpcode::kJSStoreContext:
672 // Type is empty.
673 CheckNotTyped(node);
674 break;
675 case IrOpcode::kJSCreateFunctionContext:
676 case IrOpcode::kJSCreateCatchContext:
677 case IrOpcode::kJSCreateWithContext:
678 case IrOpcode::kJSCreateBlockContext:
679 case IrOpcode::kJSCreateScriptContext: {
680 // Type is Context, and operand is Internal.
681 Node* context = NodeProperties::GetContextInput(node);
682 // TODO(bmeurer): This should say CheckTypeIs, but we don't have type
683 // OtherInternal on certain contexts, i.e. those from OsrValue inputs.
684 CheckTypeMaybe(context, Type::OtherInternal());
685 CheckTypeIs(node, Type::OtherInternal());
686 break;
687 }
688
689 case IrOpcode::kJSConstruct:
690 case IrOpcode::kJSConstructWithSpread:
691 case IrOpcode::kJSConvertReceiver:
692 // Type is Receiver.
693 CheckTypeIs(node, Type::Receiver());
694 break;
695 case IrOpcode::kJSCallForwardVarargs:
696 case IrOpcode::kJSCall:
697 case IrOpcode::kJSCallWithSpread:
698 case IrOpcode::kJSCallRuntime:
699 // Type can be anything.
700 CheckTypeIs(node, Type::Any());
701 break;
702
703 case IrOpcode::kJSForInPrepare: {
704 // TODO(bmeurer): What are the constraints on thse?
705 CheckTypeIs(node, Type::Any());
706 break;
707 }
708 case IrOpcode::kJSForInNext: {
709 CheckTypeIs(node, Type::Union(Type::Name(), Type::Undefined(), zone));
710 break;
711 }
712
713 case IrOpcode::kJSLoadMessage:
714 case IrOpcode::kJSStoreMessage:
715 break;
716
717 case IrOpcode::kJSLoadModule:
718 CheckTypeIs(node, Type::Any());
719 break;
720 case IrOpcode::kJSStoreModule:
721 CheckNotTyped(node);
722 break;
723
724 case IrOpcode::kJSGeneratorStore:
725 CheckNotTyped(node);
726 break;
727
728 case IrOpcode::kJSGeneratorRestoreContinuation:
729 CheckTypeIs(node, Type::SignedSmall());
730 break;
731
732 case IrOpcode::kJSGeneratorRestoreRegister:
733 CheckTypeIs(node, Type::Any());
734 break;
735
736 case IrOpcode::kJSStackCheck:
737 case IrOpcode::kJSDebugger:
738 // Type is empty.
739 CheckNotTyped(node);
740 break;
741
742 case IrOpcode::kComment:
743 case IrOpcode::kDebugBreak:
744 case IrOpcode::kRetain:
745 case IrOpcode::kUnsafePointerAdd:
746 CheckNotTyped(node);
747 break;
748
749 // Simplified operators
750 // -------------------------------
751 case IrOpcode::kBooleanNot:
752 // Boolean -> Boolean
753 CheckValueInputIs(node, 0, Type::Boolean());
754 CheckTypeIs(node, Type::Boolean());
755 break;
756 case IrOpcode::kNumberEqual:
757 // (Number, Number) -> Boolean
758 CheckValueInputIs(node, 0, Type::Number());
759 CheckValueInputIs(node, 1, Type::Number());
760 CheckTypeIs(node, Type::Boolean());
761 break;
762 case IrOpcode::kNumberLessThan:
763 case IrOpcode::kNumberLessThanOrEqual:
764 // (Number, Number) -> Boolean
765 CheckValueInputIs(node, 0, Type::Number());
766 CheckValueInputIs(node, 1, Type::Number());
767 CheckTypeIs(node, Type::Boolean());
768 break;
769 case IrOpcode::kSpeculativeNumberAdd:
770 case IrOpcode::kSpeculativeNumberSubtract:
771 case IrOpcode::kSpeculativeNumberMultiply:
772 case IrOpcode::kSpeculativeNumberDivide:
773 case IrOpcode::kSpeculativeNumberModulus:
774 CheckTypeIs(node, Type::Number());
775 break;
776 case IrOpcode::kSpeculativeNumberEqual:
777 case IrOpcode::kSpeculativeNumberLessThan:
778 case IrOpcode::kSpeculativeNumberLessThanOrEqual:
779 CheckTypeIs(node, Type::Boolean());
780 break;
781 case IrOpcode::kNumberAdd:
782 case IrOpcode::kNumberSubtract:
783 case IrOpcode::kNumberMultiply:
784 case IrOpcode::kNumberDivide:
785 // (Number, Number) -> Number
786 CheckValueInputIs(node, 0, Type::Number());
787 CheckValueInputIs(node, 1, Type::Number());
788 CheckTypeIs(node, Type::Number());
789 break;
790 case IrOpcode::kNumberModulus:
791 // (Number, Number) -> Number
792 CheckValueInputIs(node, 0, Type::Number());
793 CheckValueInputIs(node, 1, Type::Number());
794 CheckTypeIs(node, Type::Number());
795 break;
796 case IrOpcode::kNumberBitwiseOr:
797 case IrOpcode::kNumberBitwiseXor:
798 case IrOpcode::kNumberBitwiseAnd:
799 // (Signed32, Signed32) -> Signed32
800 CheckValueInputIs(node, 0, Type::Signed32());
801 CheckValueInputIs(node, 1, Type::Signed32());
802 CheckTypeIs(node, Type::Signed32());
803 break;
804 case IrOpcode::kSpeculativeNumberBitwiseOr:
805 case IrOpcode::kSpeculativeNumberBitwiseXor:
806 case IrOpcode::kSpeculativeNumberBitwiseAnd:
807 CheckTypeIs(node, Type::Signed32());
808 break;
809 case IrOpcode::kNumberShiftLeft:
810 case IrOpcode::kNumberShiftRight:
811 // (Signed32, Unsigned32) -> Signed32
812 CheckValueInputIs(node, 0, Type::Signed32());
813 CheckValueInputIs(node, 1, Type::Unsigned32());
814 CheckTypeIs(node, Type::Signed32());
815 break;
816 case IrOpcode::kSpeculativeNumberShiftLeft:
817 case IrOpcode::kSpeculativeNumberShiftRight:
818 CheckTypeIs(node, Type::Signed32());
819 break;
820 case IrOpcode::kNumberShiftRightLogical:
821 // (Unsigned32, Unsigned32) -> Unsigned32
822 CheckValueInputIs(node, 0, Type::Unsigned32());
823 CheckValueInputIs(node, 1, Type::Unsigned32());
824 CheckTypeIs(node, Type::Unsigned32());
825 break;
826 case IrOpcode::kSpeculativeNumberShiftRightLogical:
827 CheckTypeIs(node, Type::Unsigned32());
828 break;
829 case IrOpcode::kNumberImul:
830 // (Unsigned32, Unsigned32) -> Signed32
831 CheckValueInputIs(node, 0, Type::Unsigned32());
832 CheckValueInputIs(node, 1, Type::Unsigned32());
833 CheckTypeIs(node, Type::Signed32());
834 break;
835 case IrOpcode::kNumberClz32:
836 // Unsigned32 -> Unsigned32
837 CheckValueInputIs(node, 0, Type::Unsigned32());
838 CheckTypeIs(node, Type::Unsigned32());
839 break;
840 case IrOpcode::kNumberAtan2:
841 case IrOpcode::kNumberMax:
842 case IrOpcode::kNumberMin:
843 case IrOpcode::kNumberPow:
844 // (Number, Number) -> Number
845 CheckValueInputIs(node, 0, Type::Number());
846 CheckValueInputIs(node, 1, Type::Number());
847 CheckTypeIs(node, Type::Number());
848 break;
849 case IrOpcode::kNumberAbs:
850 case IrOpcode::kNumberCeil:
851 case IrOpcode::kNumberFloor:
852 case IrOpcode::kNumberFround:
853 case IrOpcode::kNumberAcos:
854 case IrOpcode::kNumberAcosh:
855 case IrOpcode::kNumberAsin:
856 case IrOpcode::kNumberAsinh:
857 case IrOpcode::kNumberAtan:
858 case IrOpcode::kNumberAtanh:
859 case IrOpcode::kNumberCos:
860 case IrOpcode::kNumberCosh:
861 case IrOpcode::kNumberExp:
862 case IrOpcode::kNumberExpm1:
863 case IrOpcode::kNumberLog:
864 case IrOpcode::kNumberLog1p:
865 case IrOpcode::kNumberLog2:
866 case IrOpcode::kNumberLog10:
867 case IrOpcode::kNumberCbrt:
868 case IrOpcode::kNumberRound:
869 case IrOpcode::kNumberSign:
870 case IrOpcode::kNumberSin:
871 case IrOpcode::kNumberSinh:
872 case IrOpcode::kNumberSqrt:
873 case IrOpcode::kNumberTan:
874 case IrOpcode::kNumberTanh:
875 case IrOpcode::kNumberTrunc:
876 // Number -> Number
877 CheckValueInputIs(node, 0, Type::Number());
878 CheckTypeIs(node, Type::Number());
879 break;
880 case IrOpcode::kNumberToBoolean:
881 // Number -> Boolean
882 CheckValueInputIs(node, 0, Type::Number());
883 CheckTypeIs(node, Type::Boolean());
884 break;
885 case IrOpcode::kNumberToInt32:
886 // Number -> Signed32
887 CheckValueInputIs(node, 0, Type::Number());
888 CheckTypeIs(node, Type::Signed32());
889 break;
890 case IrOpcode::kNumberToUint32:
891 case IrOpcode::kNumberToUint8Clamped:
892 // Number -> Unsigned32
893 CheckValueInputIs(node, 0, Type::Number());
894 CheckTypeIs(node, Type::Unsigned32());
895 break;
896 case IrOpcode::kPlainPrimitiveToNumber:
897 // PlainPrimitive -> Number
898 CheckValueInputIs(node, 0, Type::PlainPrimitive());
899 CheckTypeIs(node, Type::Number());
900 break;
901 case IrOpcode::kPlainPrimitiveToWord32:
902 // PlainPrimitive -> Integral32
903 CheckValueInputIs(node, 0, Type::PlainPrimitive());
904 CheckTypeIs(node, Type::Integral32());
905 break;
906 case IrOpcode::kPlainPrimitiveToFloat64:
907 // PlainPrimitive -> Number
908 CheckValueInputIs(node, 0, Type::PlainPrimitive());
909 CheckTypeIs(node, Type::Number());
910 break;
911 case IrOpcode::kStringEqual:
912 case IrOpcode::kStringLessThan:
913 case IrOpcode::kStringLessThanOrEqual:
914 // (String, String) -> Boolean
915 CheckValueInputIs(node, 0, Type::String());
916 CheckValueInputIs(node, 1, Type::String());
917 CheckTypeIs(node, Type::Boolean());
918 break;
919 case IrOpcode::kStringCharAt:
920 // (String, Unsigned32) -> String
921 CheckValueInputIs(node, 0, Type::String());
922 CheckValueInputIs(node, 1, Type::Unsigned32());
923 CheckTypeIs(node, Type::String());
924 break;
925 case IrOpcode::kStringCharCodeAt:
926 // (String, Unsigned32) -> UnsignedSmall
927 CheckValueInputIs(node, 0, Type::String());
928 CheckValueInputIs(node, 1, Type::Unsigned32());
929 CheckTypeIs(node, Type::UnsignedSmall());
930 break;
931 case IrOpcode::kStringFromCharCode:
932 // Number -> String
933 CheckValueInputIs(node, 0, Type::Number());
934 CheckTypeIs(node, Type::String());
935 break;
936 case IrOpcode::kStringFromCodePoint:
937 // (Unsigned32) -> String
938 CheckValueInputIs(node, 0, Type::Number());
939 CheckTypeIs(node, Type::String());
940 break;
941 case IrOpcode::kStringIndexOf:
942 // (String, String, SignedSmall) -> SignedSmall
943 CheckValueInputIs(node, 0, Type::String());
944 CheckValueInputIs(node, 1, Type::String());
945 CheckValueInputIs(node, 2, Type::SignedSmall());
946 CheckTypeIs(node, Type::SignedSmall());
947 break;
948
949 case IrOpcode::kReferenceEqual:
950 // (Unique, Any) -> Boolean and
951 // (Any, Unique) -> Boolean
952 CheckTypeIs(node, Type::Boolean());
953 break;
954
955 case IrOpcode::kObjectIsDetectableCallable:
956 case IrOpcode::kObjectIsNonCallable:
957 case IrOpcode::kObjectIsNumber:
958 case IrOpcode::kObjectIsReceiver:
959 case IrOpcode::kObjectIsSmi:
960 case IrOpcode::kObjectIsString:
961 case IrOpcode::kObjectIsUndetectable:
962 case IrOpcode::kArrayBufferWasNeutered:
963 CheckValueInputIs(node, 0, Type::Any());
964 CheckTypeIs(node, Type::Boolean());
965 break;
966 case IrOpcode::kNewRestParameterElements:
967 case IrOpcode::kNewUnmappedArgumentsElements:
968 CheckTypeIs(node, Type::OtherInternal());
969 break;
970 case IrOpcode::kAllocate:
971 CheckValueInputIs(node, 0, Type::PlainNumber());
972 break;
973 case IrOpcode::kEnsureWritableFastElements:
974 CheckValueInputIs(node, 0, Type::Any());
975 CheckValueInputIs(node, 1, Type::Internal());
976 CheckTypeIs(node, Type::Internal());
977 break;
978 case IrOpcode::kMaybeGrowFastElements:
979 CheckValueInputIs(node, 0, Type::Any());
980 CheckValueInputIs(node, 1, Type::Internal());
981 CheckValueInputIs(node, 2, Type::Unsigned31());
982 CheckValueInputIs(node, 3, Type::Unsigned31());
983 CheckTypeIs(node, Type::Internal());
984 break;
985 case IrOpcode::kTransitionElementsKind:
986 CheckValueInputIs(node, 0, Type::Any());
987 CheckNotTyped(node);
988 break;
989
990 case IrOpcode::kChangeTaggedSignedToInt32: {
991 // Signed32 /\ Tagged -> Signed32 /\ UntaggedInt32
992 // TODO(neis): Activate once ChangeRepresentation works in typer.
993 // Type* from = Type::Intersect(Type::Signed32(), Type::Tagged());
994 // Type* to = Type::Intersect(Type::Signed32(), Type::UntaggedInt32());
995 // CheckValueInputIs(node, 0, from));
996 // CheckTypeIs(node, to));
997 break;
998 }
999 case IrOpcode::kChangeTaggedToInt32: {
1000 // Signed32 /\ Tagged -> Signed32 /\ UntaggedInt32
1001 // TODO(neis): Activate once ChangeRepresentation works in typer.
1002 // Type* from = Type::Intersect(Type::Signed32(), Type::Tagged());
1003 // Type* to = Type::Intersect(Type::Signed32(), Type::UntaggedInt32());
1004 // CheckValueInputIs(node, 0, from));
1005 // CheckTypeIs(node, to));
1006 break;
1007 }
1008 case IrOpcode::kChangeTaggedToUint32: {
1009 // Unsigned32 /\ Tagged -> Unsigned32 /\ UntaggedInt32
1010 // TODO(neis): Activate once ChangeRepresentation works in typer.
1011 // Type* from = Type::Intersect(Type::Unsigned32(), Type::Tagged());
1012 // Type* to =Type::Intersect(Type::Unsigned32(), Type::UntaggedInt32());
1013 // CheckValueInputIs(node, 0, from));
1014 // CheckTypeIs(node, to));
1015 break;
1016 }
1017 case IrOpcode::kChangeTaggedToFloat64: {
1018 // NumberOrUndefined /\ Tagged -> Number /\ UntaggedFloat64
1019 // TODO(neis): Activate once ChangeRepresentation works in typer.
1020 // Type* from = Type::Intersect(Type::Number(), Type::Tagged());
1021 // Type* to = Type::Intersect(Type::Number(), Type::UntaggedFloat64());
1022 // CheckValueInputIs(node, 0, from));
1023 // CheckTypeIs(node, to));
1024 break;
1025 }
1026 case IrOpcode::kChangeTaggedToTaggedSigned:
1027 break;
1028 case IrOpcode::kTruncateTaggedToFloat64: {
1029 // NumberOrUndefined /\ Tagged -> Number /\ UntaggedFloat64
1030 // TODO(neis): Activate once ChangeRepresentation works in typer.
1031 // Type* from = Type::Intersect(Type::NumberOrUndefined(),
1032 // Type::Tagged());
1033 // Type* to = Type::Intersect(Type::Number(), Type::UntaggedFloat64());
1034 // CheckValueInputIs(node, 0, from));
1035 // CheckTypeIs(node, to));
1036 break;
1037 }
1038 case IrOpcode::kChangeInt31ToTaggedSigned: {
1039 // Signed31 /\ UntaggedInt32 -> Signed31 /\ Tagged
1040 // TODO(neis): Activate once ChangeRepresentation works in typer.
1041 // Type* from =Type::Intersect(Type::Signed31(), Type::UntaggedInt32());
1042 // Type* to = Type::Intersect(Type::Signed31(), Type::Tagged());
1043 // CheckValueInputIs(node, 0, from));
1044 // CheckTypeIs(node, to));
1045 break;
1046 }
1047 case IrOpcode::kChangeInt32ToTagged: {
1048 // Signed32 /\ UntaggedInt32 -> Signed32 /\ Tagged
1049 // TODO(neis): Activate once ChangeRepresentation works in typer.
1050 // Type* from =Type::Intersect(Type::Signed32(), Type::UntaggedInt32());
1051 // Type* to = Type::Intersect(Type::Signed32(), Type::Tagged());
1052 // CheckValueInputIs(node, 0, from));
1053 // CheckTypeIs(node, to));
1054 break;
1055 }
1056 case IrOpcode::kChangeUint32ToTagged: {
1057 // Unsigned32 /\ UntaggedInt32 -> Unsigned32 /\ Tagged
1058 // TODO(neis): Activate once ChangeRepresentation works in typer.
1059 // Type* from=Type::Intersect(Type::Unsigned32(),Type::UntaggedInt32());
1060 // Type* to = Type::Intersect(Type::Unsigned32(), Type::Tagged());
1061 // CheckValueInputIs(node, 0, from));
1062 // CheckTypeIs(node, to));
1063 break;
1064 }
1065 case IrOpcode::kChangeFloat64ToTagged: {
1066 // Number /\ UntaggedFloat64 -> Number /\ Tagged
1067 // TODO(neis): Activate once ChangeRepresentation works in typer.
1068 // Type* from =Type::Intersect(Type::Number(), Type::UntaggedFloat64());
1069 // Type* to = Type::Intersect(Type::Number(), Type::Tagged());
1070 // CheckValueInputIs(node, 0, from));
1071 // CheckTypeIs(node, to));
1072 break;
1073 }
1074 case IrOpcode::kChangeFloat64ToTaggedPointer:
1075 break;
1076 case IrOpcode::kChangeTaggedToBit: {
1077 // Boolean /\ TaggedPtr -> Boolean /\ UntaggedInt1
1078 // TODO(neis): Activate once ChangeRepresentation works in typer.
1079 // Type* from = Type::Intersect(Type::Boolean(), Type::TaggedPtr());
1080 // Type* to = Type::Intersect(Type::Boolean(), Type::UntaggedInt1());
1081 // CheckValueInputIs(node, 0, from));
1082 // CheckTypeIs(node, to));
1083 break;
1084 }
1085 case IrOpcode::kChangeBitToTagged: {
1086 // Boolean /\ UntaggedInt1 -> Boolean /\ TaggedPtr
1087 // TODO(neis): Activate once ChangeRepresentation works in typer.
1088 // Type* from = Type::Intersect(Type::Boolean(), Type::UntaggedInt1());
1089 // Type* to = Type::Intersect(Type::Boolean(), Type::TaggedPtr());
1090 // CheckValueInputIs(node, 0, from));
1091 // CheckTypeIs(node, to));
1092 break;
1093 }
1094 case IrOpcode::kTruncateTaggedToWord32: {
1095 // Number /\ Tagged -> Signed32 /\ UntaggedInt32
1096 // TODO(neis): Activate once ChangeRepresentation works in typer.
1097 // Type* from = Type::Intersect(Type::Number(), Type::Tagged());
1098 // Type* to = Type::Intersect(Type::Number(), Type::UntaggedInt32());
1099 // CheckValueInputIs(node, 0, from));
1100 // CheckTypeIs(node, to));
1101 break;
1102 }
1103 case IrOpcode::kTruncateTaggedToBit:
1104 break;
1105
1106 case IrOpcode::kCheckBounds:
1107 CheckValueInputIs(node, 0, Type::Any());
1108 CheckValueInputIs(node, 1, Type::Unsigned31());
1109 CheckTypeIs(node, Type::Unsigned31());
1110 break;
1111 case IrOpcode::kCheckHeapObject:
1112 CheckValueInputIs(node, 0, Type::Any());
1113 break;
1114 case IrOpcode::kCheckIf:
1115 CheckValueInputIs(node, 0, Type::Boolean());
1116 CheckNotTyped(node);
1117 break;
1118 case IrOpcode::kCheckInternalizedString:
1119 CheckValueInputIs(node, 0, Type::Any());
1120 CheckTypeIs(node, Type::InternalizedString());
1121 break;
1122 case IrOpcode::kCheckMaps:
1123 // (Any, Internal, ..., Internal) -> Any
1124 CheckValueInputIs(node, 0, Type::Any());
1125 for (int i = 1; i < node->op()->ValueInputCount(); ++i) {
1126 CheckValueInputIs(node, i, Type::Internal());
1127 }
1128 CheckNotTyped(node);
1129 break;
1130 case IrOpcode::kCheckNumber:
1131 CheckValueInputIs(node, 0, Type::Any());
1132 CheckTypeIs(node, Type::Number());
1133 break;
1134 case IrOpcode::kCheckReceiver:
1135 CheckValueInputIs(node, 0, Type::Any());
1136 CheckTypeIs(node, Type::Receiver());
1137 break;
1138 case IrOpcode::kCheckSmi:
1139 CheckValueInputIs(node, 0, Type::Any());
1140 break;
1141 case IrOpcode::kCheckString:
1142 CheckValueInputIs(node, 0, Type::Any());
1143 CheckTypeIs(node, Type::String());
1144 break;
1145
1146 case IrOpcode::kCheckedInt32Add:
1147 case IrOpcode::kCheckedInt32Sub:
1148 case IrOpcode::kCheckedInt32Div:
1149 case IrOpcode::kCheckedInt32Mod:
1150 case IrOpcode::kCheckedUint32Div:
1151 case IrOpcode::kCheckedUint32Mod:
1152 case IrOpcode::kCheckedInt32Mul:
1153 case IrOpcode::kCheckedInt32ToTaggedSigned:
1154 case IrOpcode::kCheckedUint32ToInt32:
1155 case IrOpcode::kCheckedUint32ToTaggedSigned:
1156 case IrOpcode::kCheckedFloat64ToInt32:
1157 case IrOpcode::kCheckedTaggedSignedToInt32:
1158 case IrOpcode::kCheckedTaggedToInt32:
1159 case IrOpcode::kCheckedTaggedToFloat64:
1160 case IrOpcode::kCheckedTaggedToTaggedSigned:
1161 case IrOpcode::kCheckedTaggedToTaggedPointer:
1162 case IrOpcode::kCheckedTruncateTaggedToWord32:
1163 break;
1164
1165 case IrOpcode::kCheckFloat64Hole:
1166 CheckValueInputIs(node, 0, Type::Number());
1167 CheckTypeIs(node, Type::Number());
1168 break;
1169 case IrOpcode::kCheckTaggedHole:
1170 CheckValueInputIs(node, 0, Type::Any());
1171 CheckTypeIs(node, Type::NonInternal());
1172 break;
1173 case IrOpcode::kConvertTaggedHoleToUndefined:
1174 CheckValueInputIs(node, 0, Type::Any());
1175 CheckTypeIs(node, Type::NonInternal());
1176 break;
1177
1178 case IrOpcode::kLoadField:
1179 // Object -> fieldtype
1180 // TODO(rossberg): activate once machine ops are typed.
1181 // CheckValueInputIs(node, 0, Type::Object());
1182 // CheckTypeIs(node, FieldAccessOf(node->op()).type));
1183 break;
1184 case IrOpcode::kLoadBuffer:
1185 break;
1186 case IrOpcode::kLoadElement:
1187 // Object -> elementtype
1188 // TODO(rossberg): activate once machine ops are typed.
1189 // CheckValueInputIs(node, 0, Type::Object());
1190 // CheckTypeIs(node, ElementAccessOf(node->op()).type));
1191 break;
1192 case IrOpcode::kLoadTypedElement:
1193 break;
1194 case IrOpcode::kStoreField:
1195 // (Object, fieldtype) -> _|_
1196 // TODO(rossberg): activate once machine ops are typed.
1197 // CheckValueInputIs(node, 0, Type::Object());
1198 // CheckValueInputIs(node, 1, FieldAccessOf(node->op()).type));
1199 CheckNotTyped(node);
1200 break;
1201 case IrOpcode::kStoreBuffer:
1202 break;
1203 case IrOpcode::kStoreElement:
1204 // (Object, elementtype) -> _|_
1205 // TODO(rossberg): activate once machine ops are typed.
1206 // CheckValueInputIs(node, 0, Type::Object());
1207 // CheckValueInputIs(node, 1, ElementAccessOf(node->op()).type));
1208 CheckNotTyped(node);
1209 break;
1210 case IrOpcode::kStoreTypedElement:
1211 CheckNotTyped(node);
1212 break;
1213 case IrOpcode::kNumberSilenceNaN:
1214 CheckValueInputIs(node, 0, Type::Number());
1215 CheckTypeIs(node, Type::Number());
1216 break;
1217 case IrOpcode::kTypeGuard:
1218 CheckTypeIs(node, TypeGuardTypeOf(node->op()));
1219 break;
1220
1221 // Machine operators
1222 // -----------------------
1223 case IrOpcode::kLoad:
1224 case IrOpcode::kProtectedLoad:
1225 case IrOpcode::kProtectedStore:
1226 case IrOpcode::kStore:
1227 case IrOpcode::kStackSlot:
1228 case IrOpcode::kWord32And:
1229 case IrOpcode::kWord32Or:
1230 case IrOpcode::kWord32Xor:
1231 case IrOpcode::kWord32Shl:
1232 case IrOpcode::kWord32Shr:
1233 case IrOpcode::kWord32Sar:
1234 case IrOpcode::kWord32Ror:
1235 case IrOpcode::kWord32Equal:
1236 case IrOpcode::kWord32Clz:
1237 case IrOpcode::kWord32Ctz:
1238 case IrOpcode::kWord32ReverseBits:
1239 case IrOpcode::kWord32ReverseBytes:
1240 case IrOpcode::kWord32Popcnt:
1241 case IrOpcode::kWord64And:
1242 case IrOpcode::kWord64Or:
1243 case IrOpcode::kWord64Xor:
1244 case IrOpcode::kWord64Shl:
1245 case IrOpcode::kWord64Shr:
1246 case IrOpcode::kWord64Sar:
1247 case IrOpcode::kWord64Ror:
1248 case IrOpcode::kWord64Clz:
1249 case IrOpcode::kWord64Popcnt:
1250 case IrOpcode::kWord64Ctz:
1251 case IrOpcode::kWord64ReverseBits:
1252 case IrOpcode::kWord64ReverseBytes:
1253 case IrOpcode::kWord64Equal:
1254 case IrOpcode::kInt32Add:
1255 case IrOpcode::kInt32AddWithOverflow:
1256 case IrOpcode::kInt32Sub:
1257 case IrOpcode::kInt32SubWithOverflow:
1258 case IrOpcode::kInt32Mul:
1259 case IrOpcode::kInt32MulWithOverflow:
1260 case IrOpcode::kInt32MulHigh:
1261 case IrOpcode::kInt32Div:
1262 case IrOpcode::kInt32Mod:
1263 case IrOpcode::kInt32LessThan:
1264 case IrOpcode::kInt32LessThanOrEqual:
1265 case IrOpcode::kUint32Div:
1266 case IrOpcode::kUint32Mod:
1267 case IrOpcode::kUint32MulHigh:
1268 case IrOpcode::kUint32LessThan:
1269 case IrOpcode::kUint32LessThanOrEqual:
1270 case IrOpcode::kInt64Add:
1271 case IrOpcode::kInt64AddWithOverflow:
1272 case IrOpcode::kInt64Sub:
1273 case IrOpcode::kInt64SubWithOverflow:
1274 case IrOpcode::kInt64Mul:
1275 case IrOpcode::kInt64Div:
1276 case IrOpcode::kInt64Mod:
1277 case IrOpcode::kInt64LessThan:
1278 case IrOpcode::kInt64LessThanOrEqual:
1279 case IrOpcode::kUint64Div:
1280 case IrOpcode::kUint64Mod:
1281 case IrOpcode::kUint64LessThan:
1282 case IrOpcode::kUint64LessThanOrEqual:
1283 case IrOpcode::kFloat32Add:
1284 case IrOpcode::kFloat32Sub:
1285 case IrOpcode::kFloat32Neg:
1286 case IrOpcode::kFloat32Mul:
1287 case IrOpcode::kFloat32Div:
1288 case IrOpcode::kFloat32Abs:
1289 case IrOpcode::kFloat32Sqrt:
1290 case IrOpcode::kFloat32Equal:
1291 case IrOpcode::kFloat32LessThan:
1292 case IrOpcode::kFloat32LessThanOrEqual:
1293 case IrOpcode::kFloat32Max:
1294 case IrOpcode::kFloat32Min:
1295 case IrOpcode::kFloat64Add:
1296 case IrOpcode::kFloat64Sub:
1297 case IrOpcode::kFloat64Neg:
1298 case IrOpcode::kFloat64Mul:
1299 case IrOpcode::kFloat64Div:
1300 case IrOpcode::kFloat64Mod:
1301 case IrOpcode::kFloat64Max:
1302 case IrOpcode::kFloat64Min:
1303 case IrOpcode::kFloat64Abs:
1304 case IrOpcode::kFloat64Acos:
1305 case IrOpcode::kFloat64Acosh:
1306 case IrOpcode::kFloat64Asin:
1307 case IrOpcode::kFloat64Asinh:
1308 case IrOpcode::kFloat64Atan:
1309 case IrOpcode::kFloat64Atan2:
1310 case IrOpcode::kFloat64Atanh:
1311 case IrOpcode::kFloat64Cbrt:
1312 case IrOpcode::kFloat64Cos:
1313 case IrOpcode::kFloat64Cosh:
1314 case IrOpcode::kFloat64Exp:
1315 case IrOpcode::kFloat64Expm1:
1316 case IrOpcode::kFloat64Log:
1317 case IrOpcode::kFloat64Log1p:
1318 case IrOpcode::kFloat64Log10:
1319 case IrOpcode::kFloat64Log2:
1320 case IrOpcode::kFloat64Pow:
1321 case IrOpcode::kFloat64Sin:
1322 case IrOpcode::kFloat64Sinh:
1323 case IrOpcode::kFloat64Sqrt:
1324 case IrOpcode::kFloat64Tan:
1325 case IrOpcode::kFloat64Tanh:
1326 case IrOpcode::kFloat32RoundDown:
1327 case IrOpcode::kFloat64RoundDown:
1328 case IrOpcode::kFloat32RoundUp:
1329 case IrOpcode::kFloat64RoundUp:
1330 case IrOpcode::kFloat32RoundTruncate:
1331 case IrOpcode::kFloat64RoundTruncate:
1332 case IrOpcode::kFloat64RoundTiesAway:
1333 case IrOpcode::kFloat32RoundTiesEven:
1334 case IrOpcode::kFloat64RoundTiesEven:
1335 case IrOpcode::kFloat64Equal:
1336 case IrOpcode::kFloat64LessThan:
1337 case IrOpcode::kFloat64LessThanOrEqual:
1338 case IrOpcode::kTruncateInt64ToInt32:
1339 case IrOpcode::kRoundFloat64ToInt32:
1340 case IrOpcode::kRoundInt32ToFloat32:
1341 case IrOpcode::kRoundInt64ToFloat32:
1342 case IrOpcode::kRoundInt64ToFloat64:
1343 case IrOpcode::kRoundUint32ToFloat32:
1344 case IrOpcode::kRoundUint64ToFloat64:
1345 case IrOpcode::kRoundUint64ToFloat32:
1346 case IrOpcode::kTruncateFloat64ToFloat32:
1347 case IrOpcode::kTruncateFloat64ToWord32:
1348 case IrOpcode::kBitcastFloat32ToInt32:
1349 case IrOpcode::kBitcastFloat64ToInt64:
1350 case IrOpcode::kBitcastInt32ToFloat32:
1351 case IrOpcode::kBitcastInt64ToFloat64:
1352 case IrOpcode::kBitcastTaggedToWord:
1353 case IrOpcode::kBitcastWordToTagged:
1354 case IrOpcode::kBitcastWordToTaggedSigned:
1355 case IrOpcode::kChangeInt32ToInt64:
1356 case IrOpcode::kChangeUint32ToUint64:
1357 case IrOpcode::kChangeInt32ToFloat64:
1358 case IrOpcode::kChangeUint32ToFloat64:
1359 case IrOpcode::kChangeFloat32ToFloat64:
1360 case IrOpcode::kChangeFloat64ToInt32:
1361 case IrOpcode::kChangeFloat64ToUint32:
1362 case IrOpcode::kFloat64SilenceNaN:
1363 case IrOpcode::kTruncateFloat64ToUint32:
1364 case IrOpcode::kTruncateFloat32ToInt32:
1365 case IrOpcode::kTruncateFloat32ToUint32:
1366 case IrOpcode::kTryTruncateFloat32ToInt64:
1367 case IrOpcode::kTryTruncateFloat64ToInt64:
1368 case IrOpcode::kTryTruncateFloat32ToUint64:
1369 case IrOpcode::kTryTruncateFloat64ToUint64:
1370 case IrOpcode::kFloat64ExtractLowWord32:
1371 case IrOpcode::kFloat64ExtractHighWord32:
1372 case IrOpcode::kFloat64InsertLowWord32:
1373 case IrOpcode::kFloat64InsertHighWord32:
1374 case IrOpcode::kInt32PairAdd:
1375 case IrOpcode::kInt32PairSub:
1376 case IrOpcode::kInt32PairMul:
1377 case IrOpcode::kWord32PairShl:
1378 case IrOpcode::kWord32PairShr:
1379 case IrOpcode::kWord32PairSar:
1380 case IrOpcode::kLoadStackPointer:
1381 case IrOpcode::kLoadFramePointer:
1382 case IrOpcode::kLoadParentFramePointer:
1383 case IrOpcode::kUnalignedLoad:
1384 case IrOpcode::kUnalignedStore:
1385 case IrOpcode::kCheckedLoad:
1386 case IrOpcode::kCheckedStore:
1387 case IrOpcode::kAtomicLoad:
1388 case IrOpcode::kAtomicStore:
1389
1390 #define SIMD_MACHINE_OP_CASE(Name) case IrOpcode::k##Name:
1391 MACHINE_SIMD_OP_LIST(SIMD_MACHINE_OP_CASE)
1392 #undef SIMD_MACHINE_OP_CASE
1393
1394 // TODO(rossberg): Check.
1395 break;
1396 }
1397 } // NOLINT(readability/fn_size)
1398
Run(Graph * graph,Typing typing,CheckInputs check_inputs)1399 void Verifier::Run(Graph* graph, Typing typing, CheckInputs check_inputs) {
1400 CHECK_NOT_NULL(graph->start());
1401 CHECK_NOT_NULL(graph->end());
1402 Zone zone(graph->zone()->allocator(), ZONE_NAME);
1403 Visitor visitor(&zone, typing, check_inputs);
1404 AllNodes all(&zone, graph);
1405 for (Node* node : all.reachable) visitor.Check(node);
1406
1407 // Check the uniqueness of projections.
1408 for (Node* proj : all.reachable) {
1409 if (proj->opcode() != IrOpcode::kProjection) continue;
1410 Node* node = proj->InputAt(0);
1411 for (Node* other : node->uses()) {
1412 if (all.IsLive(other) && other != proj &&
1413 other->opcode() == IrOpcode::kProjection &&
1414 ProjectionIndexOf(other->op()) == ProjectionIndexOf(proj->op())) {
1415 V8_Fatal(__FILE__, __LINE__,
1416 "Node #%d:%s has duplicate projections #%d and #%d",
1417 node->id(), node->op()->mnemonic(), proj->id(), other->id());
1418 }
1419 }
1420 }
1421 }
1422
1423
1424 // -----------------------------------------------------------------------------
1425
HasDominatingDef(Schedule * schedule,Node * node,BasicBlock * container,BasicBlock * use_block,int use_pos)1426 static bool HasDominatingDef(Schedule* schedule, Node* node,
1427 BasicBlock* container, BasicBlock* use_block,
1428 int use_pos) {
1429 BasicBlock* block = use_block;
1430 while (true) {
1431 while (use_pos >= 0) {
1432 if (block->NodeAt(use_pos) == node) return true;
1433 use_pos--;
1434 }
1435 block = block->dominator();
1436 if (block == nullptr) break;
1437 use_pos = static_cast<int>(block->NodeCount()) - 1;
1438 if (node == block->control_input()) return true;
1439 }
1440 return false;
1441 }
1442
1443
Dominates(Schedule * schedule,Node * dominator,Node * dominatee)1444 static bool Dominates(Schedule* schedule, Node* dominator, Node* dominatee) {
1445 BasicBlock* dom = schedule->block(dominator);
1446 BasicBlock* sub = schedule->block(dominatee);
1447 while (sub != nullptr) {
1448 if (sub == dom) {
1449 return true;
1450 }
1451 sub = sub->dominator();
1452 }
1453 return false;
1454 }
1455
1456
CheckInputsDominate(Schedule * schedule,BasicBlock * block,Node * node,int use_pos)1457 static void CheckInputsDominate(Schedule* schedule, BasicBlock* block,
1458 Node* node, int use_pos) {
1459 for (int j = node->op()->ValueInputCount() - 1; j >= 0; j--) {
1460 BasicBlock* use_block = block;
1461 if (node->opcode() == IrOpcode::kPhi) {
1462 use_block = use_block->PredecessorAt(j);
1463 use_pos = static_cast<int>(use_block->NodeCount()) - 1;
1464 }
1465 Node* input = node->InputAt(j);
1466 if (!HasDominatingDef(schedule, node->InputAt(j), block, use_block,
1467 use_pos)) {
1468 V8_Fatal(__FILE__, __LINE__,
1469 "Node #%d:%s in B%d is not dominated by input@%d #%d:%s",
1470 node->id(), node->op()->mnemonic(), block->rpo_number(), j,
1471 input->id(), input->op()->mnemonic());
1472 }
1473 }
1474 // Ensure that nodes are dominated by their control inputs;
1475 // kEnd is an exception, as unreachable blocks resulting from kMerge
1476 // are not in the RPO.
1477 if (node->op()->ControlInputCount() == 1 &&
1478 node->opcode() != IrOpcode::kEnd) {
1479 Node* ctl = NodeProperties::GetControlInput(node);
1480 if (!Dominates(schedule, ctl, node)) {
1481 V8_Fatal(__FILE__, __LINE__,
1482 "Node #%d:%s in B%d is not dominated by control input #%d:%s",
1483 node->id(), node->op()->mnemonic(), block->rpo_number(),
1484 ctl->id(), ctl->op()->mnemonic());
1485 }
1486 }
1487 }
1488
1489
Run(Schedule * schedule)1490 void ScheduleVerifier::Run(Schedule* schedule) {
1491 const size_t count = schedule->BasicBlockCount();
1492 Zone tmp_zone(schedule->zone()->allocator(), ZONE_NAME);
1493 Zone* zone = &tmp_zone;
1494 BasicBlock* start = schedule->start();
1495 BasicBlockVector* rpo_order = schedule->rpo_order();
1496
1497 // Verify the RPO order contains only blocks from this schedule.
1498 CHECK_GE(count, rpo_order->size());
1499 for (BasicBlockVector::iterator b = rpo_order->begin(); b != rpo_order->end();
1500 ++b) {
1501 CHECK_EQ((*b), schedule->GetBlockById((*b)->id()));
1502 // All predecessors and successors should be in rpo and in this schedule.
1503 for (BasicBlock const* predecessor : (*b)->predecessors()) {
1504 CHECK_GE(predecessor->rpo_number(), 0);
1505 CHECK_EQ(predecessor, schedule->GetBlockById(predecessor->id()));
1506 }
1507 for (BasicBlock const* successor : (*b)->successors()) {
1508 CHECK_GE(successor->rpo_number(), 0);
1509 CHECK_EQ(successor, schedule->GetBlockById(successor->id()));
1510 }
1511 }
1512
1513 // Verify RPO numbers of blocks.
1514 CHECK_EQ(start, rpo_order->at(0)); // Start should be first.
1515 for (size_t b = 0; b < rpo_order->size(); b++) {
1516 BasicBlock* block = rpo_order->at(b);
1517 CHECK_EQ(static_cast<int>(b), block->rpo_number());
1518 BasicBlock* dom = block->dominator();
1519 if (b == 0) {
1520 // All blocks except start should have a dominator.
1521 CHECK_NULL(dom);
1522 } else {
1523 // Check that the immediate dominator appears somewhere before the block.
1524 CHECK_NOT_NULL(dom);
1525 CHECK_LT(dom->rpo_number(), block->rpo_number());
1526 }
1527 }
1528
1529 // Verify that all blocks reachable from start are in the RPO.
1530 BoolVector marked(static_cast<int>(count), false, zone);
1531 {
1532 ZoneQueue<BasicBlock*> queue(zone);
1533 queue.push(start);
1534 marked[start->id().ToSize()] = true;
1535 while (!queue.empty()) {
1536 BasicBlock* block = queue.front();
1537 queue.pop();
1538 for (size_t s = 0; s < block->SuccessorCount(); s++) {
1539 BasicBlock* succ = block->SuccessorAt(s);
1540 if (!marked[succ->id().ToSize()]) {
1541 marked[succ->id().ToSize()] = true;
1542 queue.push(succ);
1543 }
1544 }
1545 }
1546 }
1547 // Verify marked blocks are in the RPO.
1548 for (size_t i = 0; i < count; i++) {
1549 BasicBlock* block = schedule->GetBlockById(BasicBlock::Id::FromSize(i));
1550 if (marked[i]) {
1551 CHECK_GE(block->rpo_number(), 0);
1552 CHECK_EQ(block, rpo_order->at(block->rpo_number()));
1553 }
1554 }
1555 // Verify RPO blocks are marked.
1556 for (size_t b = 0; b < rpo_order->size(); b++) {
1557 CHECK(marked[rpo_order->at(b)->id().ToSize()]);
1558 }
1559
1560 {
1561 // Verify the dominance relation.
1562 ZoneVector<BitVector*> dominators(zone);
1563 dominators.resize(count, nullptr);
1564
1565 // Compute a set of all the nodes that dominate a given node by using
1566 // a forward fixpoint. O(n^2).
1567 ZoneQueue<BasicBlock*> queue(zone);
1568 queue.push(start);
1569 dominators[start->id().ToSize()] =
1570 new (zone) BitVector(static_cast<int>(count), zone);
1571 while (!queue.empty()) {
1572 BasicBlock* block = queue.front();
1573 queue.pop();
1574 BitVector* block_doms = dominators[block->id().ToSize()];
1575 BasicBlock* idom = block->dominator();
1576 if (idom != nullptr && !block_doms->Contains(idom->id().ToInt())) {
1577 V8_Fatal(__FILE__, __LINE__, "Block B%d is not dominated by B%d",
1578 block->rpo_number(), idom->rpo_number());
1579 }
1580 for (size_t s = 0; s < block->SuccessorCount(); s++) {
1581 BasicBlock* succ = block->SuccessorAt(s);
1582 BitVector* succ_doms = dominators[succ->id().ToSize()];
1583
1584 if (succ_doms == nullptr) {
1585 // First time visiting the node. S.doms = B U B.doms
1586 succ_doms = new (zone) BitVector(static_cast<int>(count), zone);
1587 succ_doms->CopyFrom(*block_doms);
1588 succ_doms->Add(block->id().ToInt());
1589 dominators[succ->id().ToSize()] = succ_doms;
1590 queue.push(succ);
1591 } else {
1592 // Nth time visiting the successor. S.doms = S.doms ^ (B U B.doms)
1593 bool had = succ_doms->Contains(block->id().ToInt());
1594 if (had) succ_doms->Remove(block->id().ToInt());
1595 if (succ_doms->IntersectIsChanged(*block_doms)) queue.push(succ);
1596 if (had) succ_doms->Add(block->id().ToInt());
1597 }
1598 }
1599 }
1600
1601 // Verify the immediateness of dominators.
1602 for (BasicBlockVector::iterator b = rpo_order->begin();
1603 b != rpo_order->end(); ++b) {
1604 BasicBlock* block = *b;
1605 BasicBlock* idom = block->dominator();
1606 if (idom == nullptr) continue;
1607 BitVector* block_doms = dominators[block->id().ToSize()];
1608
1609 for (BitVector::Iterator it(block_doms); !it.Done(); it.Advance()) {
1610 BasicBlock* dom =
1611 schedule->GetBlockById(BasicBlock::Id::FromInt(it.Current()));
1612 if (dom != idom &&
1613 !dominators[idom->id().ToSize()]->Contains(dom->id().ToInt())) {
1614 V8_Fatal(__FILE__, __LINE__,
1615 "Block B%d is not immediately dominated by B%d",
1616 block->rpo_number(), idom->rpo_number());
1617 }
1618 }
1619 }
1620 }
1621
1622 // Verify phis are placed in the block of their control input.
1623 for (BasicBlockVector::iterator b = rpo_order->begin(); b != rpo_order->end();
1624 ++b) {
1625 for (BasicBlock::const_iterator i = (*b)->begin(); i != (*b)->end(); ++i) {
1626 Node* phi = *i;
1627 if (phi->opcode() != IrOpcode::kPhi) continue;
1628 // TODO(titzer): Nasty special case. Phis from RawMachineAssembler
1629 // schedules don't have control inputs.
1630 if (phi->InputCount() > phi->op()->ValueInputCount()) {
1631 Node* control = NodeProperties::GetControlInput(phi);
1632 CHECK(control->opcode() == IrOpcode::kMerge ||
1633 control->opcode() == IrOpcode::kLoop);
1634 CHECK_EQ((*b), schedule->block(control));
1635 }
1636 }
1637 }
1638
1639 // Verify that all uses are dominated by their definitions.
1640 for (BasicBlockVector::iterator b = rpo_order->begin(); b != rpo_order->end();
1641 ++b) {
1642 BasicBlock* block = *b;
1643
1644 // Check inputs to control for this block.
1645 Node* control = block->control_input();
1646 if (control != nullptr) {
1647 CHECK_EQ(block, schedule->block(control));
1648 CheckInputsDominate(schedule, block, control,
1649 static_cast<int>(block->NodeCount()) - 1);
1650 }
1651 // Check inputs for all nodes in the block.
1652 for (size_t i = 0; i < block->NodeCount(); i++) {
1653 Node* node = block->NodeAt(i);
1654 CheckInputsDominate(schedule, block, node, static_cast<int>(i) - 1);
1655 }
1656 }
1657 }
1658
1659
1660 #ifdef DEBUG
1661
1662 // static
VerifyNode(Node * node)1663 void Verifier::VerifyNode(Node* node) {
1664 CHECK_EQ(OperatorProperties::GetTotalInputCount(node->op()),
1665 node->InputCount());
1666 // If this node has no effect or no control outputs,
1667 // we check that no its uses are effect or control inputs.
1668 bool check_no_control = node->op()->ControlOutputCount() == 0;
1669 bool check_no_effect = node->op()->EffectOutputCount() == 0;
1670 bool check_no_frame_state = node->opcode() != IrOpcode::kFrameState;
1671 if (check_no_effect || check_no_control) {
1672 for (Edge edge : node->use_edges()) {
1673 Node* const user = edge.from();
1674 CHECK(!user->IsDead());
1675 if (NodeProperties::IsControlEdge(edge)) {
1676 CHECK(!check_no_control);
1677 } else if (NodeProperties::IsEffectEdge(edge)) {
1678 CHECK(!check_no_effect);
1679 } else if (NodeProperties::IsFrameStateEdge(edge)) {
1680 CHECK(!check_no_frame_state);
1681 }
1682 }
1683 }
1684 // Frame state input should be a frame state (or sentinel).
1685 if (OperatorProperties::GetFrameStateInputCount(node->op()) > 0) {
1686 Node* input = NodeProperties::GetFrameStateInput(node);
1687 CHECK(input->opcode() == IrOpcode::kFrameState ||
1688 input->opcode() == IrOpcode::kStart ||
1689 input->opcode() == IrOpcode::kDead);
1690 }
1691 // Effect inputs should be effect-producing nodes (or sentinels).
1692 for (int i = 0; i < node->op()->EffectInputCount(); i++) {
1693 Node* input = NodeProperties::GetEffectInput(node, i);
1694 CHECK(input->op()->EffectOutputCount() > 0 ||
1695 input->opcode() == IrOpcode::kDead);
1696 }
1697 // Control inputs should be control-producing nodes (or sentinels).
1698 for (int i = 0; i < node->op()->ControlInputCount(); i++) {
1699 Node* input = NodeProperties::GetControlInput(node, i);
1700 CHECK(input->op()->ControlOutputCount() > 0 ||
1701 input->opcode() == IrOpcode::kDead);
1702 }
1703 }
1704
1705
VerifyEdgeInputReplacement(const Edge & edge,const Node * replacement)1706 void Verifier::VerifyEdgeInputReplacement(const Edge& edge,
1707 const Node* replacement) {
1708 // Check that the user does not misuse the replacement.
1709 DCHECK(!NodeProperties::IsControlEdge(edge) ||
1710 replacement->op()->ControlOutputCount() > 0);
1711 DCHECK(!NodeProperties::IsEffectEdge(edge) ||
1712 replacement->op()->EffectOutputCount() > 0);
1713 DCHECK(!NodeProperties::IsFrameStateEdge(edge) ||
1714 replacement->opcode() == IrOpcode::kFrameState);
1715 }
1716
1717 #endif // DEBUG
1718
1719 } // namespace compiler
1720 } // namespace internal
1721 } // namespace v8
1722