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: 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: 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 } 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 } 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 } 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 } 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 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 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 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 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 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 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 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 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