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