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 "test/unittests/compiler/node-test-utils.h" 6 7 #include <vector> 8 9 #include "src/assembler.h" 10 #include "src/compiler/common-operator.h" 11 #include "src/compiler/js-operator.h" 12 #include "src/compiler/node-properties.h" 13 #include "src/compiler/simplified-operator.h" 14 #include "src/handles-inl.h" 15 #include "src/objects.h" 16 17 using testing::_; 18 using testing::MakeMatcher; 19 using testing::MatcherInterface; 20 using testing::MatchResultListener; 21 using testing::StringMatchResultListener; 22 23 namespace v8 { 24 namespace internal { 25 26 bool operator==(Handle<HeapObject> const& lhs, Handle<HeapObject> const& rhs) { 27 return lhs.is_identical_to(rhs); 28 } 29 30 namespace compiler { 31 32 namespace { 33 34 template <typename T> 35 bool PrintMatchAndExplain(const T& value, const std::string& value_name, 36 const Matcher<T>& value_matcher, 37 MatchResultListener* listener) { 38 StringMatchResultListener value_listener; 39 if (!value_matcher.MatchAndExplain(value, &value_listener)) { 40 *listener << "whose " << value_name << " " << value << " doesn't match"; 41 if (value_listener.str() != "") { 42 *listener << ", " << value_listener.str(); 43 } 44 return false; 45 } 46 return true; 47 } 48 49 50 class NodeMatcher : public MatcherInterface<Node*> { 51 public: 52 explicit NodeMatcher(IrOpcode::Value opcode) : opcode_(opcode) {} 53 54 void DescribeTo(std::ostream* os) const override { 55 *os << "is a " << IrOpcode::Mnemonic(opcode_) << " node"; 56 } 57 58 bool MatchAndExplain(Node* node, 59 MatchResultListener* listener) const override { 60 if (node == NULL) { 61 *listener << "which is NULL"; 62 return false; 63 } 64 if (node->opcode() != opcode_) { 65 *listener << "whose opcode is " << IrOpcode::Mnemonic(node->opcode()) 66 << " but should have been " << IrOpcode::Mnemonic(opcode_); 67 return false; 68 } 69 return true; 70 } 71 72 private: 73 const IrOpcode::Value opcode_; 74 }; 75 76 77 class IsBranchMatcher final : public NodeMatcher { 78 public: 79 IsBranchMatcher(const Matcher<Node*>& value_matcher, 80 const Matcher<Node*>& control_matcher) 81 : NodeMatcher(IrOpcode::kBranch), 82 value_matcher_(value_matcher), 83 control_matcher_(control_matcher) {} 84 85 void DescribeTo(std::ostream* os) const final { 86 NodeMatcher::DescribeTo(os); 87 *os << " whose value ("; 88 value_matcher_.DescribeTo(os); 89 *os << ") and control ("; 90 control_matcher_.DescribeTo(os); 91 *os << ")"; 92 } 93 94 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 95 return (NodeMatcher::MatchAndExplain(node, listener) && 96 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), 97 "value", value_matcher_, listener) && 98 PrintMatchAndExplain(NodeProperties::GetControlInput(node), 99 "control", control_matcher_, listener)); 100 } 101 102 private: 103 const Matcher<Node*> value_matcher_; 104 const Matcher<Node*> control_matcher_; 105 }; 106 107 108 class IsSwitchMatcher final : public NodeMatcher { 109 public: 110 IsSwitchMatcher(const Matcher<Node*>& value_matcher, 111 const Matcher<Node*>& control_matcher) 112 : NodeMatcher(IrOpcode::kSwitch), 113 value_matcher_(value_matcher), 114 control_matcher_(control_matcher) {} 115 116 void DescribeTo(std::ostream* os) const final { 117 NodeMatcher::DescribeTo(os); 118 *os << " whose value ("; 119 value_matcher_.DescribeTo(os); 120 *os << ") and control ("; 121 control_matcher_.DescribeTo(os); 122 *os << ")"; 123 } 124 125 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 126 return (NodeMatcher::MatchAndExplain(node, listener) && 127 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), 128 "value", value_matcher_, listener) && 129 PrintMatchAndExplain(NodeProperties::GetControlInput(node), 130 "control", control_matcher_, listener)); 131 } 132 133 private: 134 const Matcher<Node*> value_matcher_; 135 const Matcher<Node*> control_matcher_; 136 }; 137 138 139 class IsIfValueMatcher final : public NodeMatcher { 140 public: 141 IsIfValueMatcher(const Matcher<int32_t>& value_matcher, 142 const Matcher<Node*>& control_matcher) 143 : NodeMatcher(IrOpcode::kIfValue), 144 value_matcher_(value_matcher), 145 control_matcher_(control_matcher) {} 146 147 void DescribeTo(std::ostream* os) const final { 148 NodeMatcher::DescribeTo(os); 149 *os << " whose value ("; 150 value_matcher_.DescribeTo(os); 151 *os << ") and control ("; 152 control_matcher_.DescribeTo(os); 153 *os << ")"; 154 } 155 156 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 157 return (NodeMatcher::MatchAndExplain(node, listener) && 158 PrintMatchAndExplain(OpParameter<int32_t>(node->op()), "value", 159 value_matcher_, listener) && 160 PrintMatchAndExplain(NodeProperties::GetControlInput(node), 161 "control", control_matcher_, listener)); 162 } 163 164 private: 165 const Matcher<int32_t> value_matcher_; 166 const Matcher<Node*> control_matcher_; 167 }; 168 169 170 class IsControl1Matcher final : public NodeMatcher { 171 public: 172 IsControl1Matcher(IrOpcode::Value opcode, 173 const Matcher<Node*>& control_matcher) 174 : NodeMatcher(opcode), control_matcher_(control_matcher) {} 175 176 void DescribeTo(std::ostream* os) const final { 177 NodeMatcher::DescribeTo(os); 178 *os << " whose control ("; 179 control_matcher_.DescribeTo(os); 180 *os << ")"; 181 } 182 183 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 184 return (NodeMatcher::MatchAndExplain(node, listener) && 185 PrintMatchAndExplain(NodeProperties::GetControlInput(node), 186 "control", control_matcher_, listener)); 187 } 188 189 private: 190 const Matcher<Node*> control_matcher_; 191 }; 192 193 194 class IsControl2Matcher final : public NodeMatcher { 195 public: 196 IsControl2Matcher(IrOpcode::Value opcode, 197 const Matcher<Node*>& control0_matcher, 198 const Matcher<Node*>& control1_matcher) 199 : NodeMatcher(opcode), 200 control0_matcher_(control0_matcher), 201 control1_matcher_(control1_matcher) {} 202 203 void DescribeTo(std::ostream* os) const final { 204 NodeMatcher::DescribeTo(os); 205 *os << " whose control0 ("; 206 control0_matcher_.DescribeTo(os); 207 *os << ") and control1 ("; 208 control1_matcher_.DescribeTo(os); 209 *os << ")"; 210 } 211 212 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 213 return (NodeMatcher::MatchAndExplain(node, listener) && 214 PrintMatchAndExplain(NodeProperties::GetControlInput(node, 0), 215 "control0", control0_matcher_, listener) && 216 PrintMatchAndExplain(NodeProperties::GetControlInput(node, 1), 217 "control1", control1_matcher_, listener)); 218 } 219 220 private: 221 const Matcher<Node*> control0_matcher_; 222 const Matcher<Node*> control1_matcher_; 223 }; 224 225 226 class IsControl3Matcher final : public NodeMatcher { 227 public: 228 IsControl3Matcher(IrOpcode::Value opcode, 229 const Matcher<Node*>& control0_matcher, 230 const Matcher<Node*>& control1_matcher, 231 const Matcher<Node*>& control2_matcher) 232 : NodeMatcher(opcode), 233 control0_matcher_(control0_matcher), 234 control1_matcher_(control1_matcher), 235 control2_matcher_(control2_matcher) {} 236 237 void DescribeTo(std::ostream* os) const final { 238 NodeMatcher::DescribeTo(os); 239 *os << " whose control0 ("; 240 control0_matcher_.DescribeTo(os); 241 *os << ") and control1 ("; 242 control1_matcher_.DescribeTo(os); 243 *os << ") and control2 ("; 244 control2_matcher_.DescribeTo(os); 245 *os << ")"; 246 } 247 248 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 249 return (NodeMatcher::MatchAndExplain(node, listener) && 250 PrintMatchAndExplain(NodeProperties::GetControlInput(node, 0), 251 "control0", control0_matcher_, listener) && 252 PrintMatchAndExplain(NodeProperties::GetControlInput(node, 1), 253 "control1", control1_matcher_, listener) && 254 PrintMatchAndExplain(NodeProperties::GetControlInput(node, 2), 255 "control2", control2_matcher_, listener)); 256 } 257 258 private: 259 const Matcher<Node*> control0_matcher_; 260 const Matcher<Node*> control1_matcher_; 261 const Matcher<Node*> control2_matcher_; 262 }; 263 264 265 class IsBeginRegionMatcher final : public NodeMatcher { 266 public: 267 explicit IsBeginRegionMatcher(const Matcher<Node*>& effect_matcher) 268 : NodeMatcher(IrOpcode::kBeginRegion), effect_matcher_(effect_matcher) {} 269 270 void DescribeTo(std::ostream* os) const final { 271 NodeMatcher::DescribeTo(os); 272 *os << " whose effect ("; 273 effect_matcher_.DescribeTo(os); 274 *os << ")"; 275 } 276 277 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 278 return (NodeMatcher::MatchAndExplain(node, listener) && 279 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", 280 effect_matcher_, listener)); 281 } 282 283 private: 284 const Matcher<Node*> effect_matcher_; 285 }; 286 287 288 class IsFinishRegionMatcher final : public NodeMatcher { 289 public: 290 IsFinishRegionMatcher(const Matcher<Node*>& value_matcher, 291 const Matcher<Node*>& effect_matcher) 292 : NodeMatcher(IrOpcode::kFinishRegion), 293 value_matcher_(value_matcher), 294 effect_matcher_(effect_matcher) {} 295 296 void DescribeTo(std::ostream* os) const final { 297 NodeMatcher::DescribeTo(os); 298 *os << " whose value ("; 299 value_matcher_.DescribeTo(os); 300 *os << ") and effect ("; 301 effect_matcher_.DescribeTo(os); 302 *os << ")"; 303 } 304 305 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 306 return (NodeMatcher::MatchAndExplain(node, listener) && 307 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), 308 "value", value_matcher_, listener) && 309 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", 310 effect_matcher_, listener)); 311 } 312 313 private: 314 const Matcher<Node*> value_matcher_; 315 const Matcher<Node*> effect_matcher_; 316 }; 317 318 319 class IsReturnMatcher final : public NodeMatcher { 320 public: 321 IsReturnMatcher(const Matcher<Node*>& value_matcher, 322 const Matcher<Node*>& effect_matcher, 323 const Matcher<Node*>& control_matcher) 324 : NodeMatcher(IrOpcode::kReturn), 325 value_matcher_(value_matcher), 326 effect_matcher_(effect_matcher), 327 control_matcher_(control_matcher) {} 328 329 void DescribeTo(std::ostream* os) const final { 330 NodeMatcher::DescribeTo(os); 331 *os << " whose value ("; 332 value_matcher_.DescribeTo(os); 333 *os << ") and effect ("; 334 effect_matcher_.DescribeTo(os); 335 *os << ") and control ("; 336 control_matcher_.DescribeTo(os); 337 *os << ")"; 338 } 339 340 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 341 return (NodeMatcher::MatchAndExplain(node, listener) && 342 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), 343 "value", value_matcher_, listener) && 344 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", 345 effect_matcher_, listener) && 346 PrintMatchAndExplain(NodeProperties::GetControlInput(node), 347 "control", control_matcher_, listener)); 348 } 349 350 private: 351 const Matcher<Node*> value_matcher_; 352 const Matcher<Node*> effect_matcher_; 353 const Matcher<Node*> control_matcher_; 354 }; 355 356 357 class IsTerminateMatcher final : public NodeMatcher { 358 public: 359 IsTerminateMatcher(const Matcher<Node*>& effect_matcher, 360 const Matcher<Node*>& control_matcher) 361 : NodeMatcher(IrOpcode::kTerminate), 362 effect_matcher_(effect_matcher), 363 control_matcher_(control_matcher) {} 364 365 void DescribeTo(std::ostream* os) const final { 366 NodeMatcher::DescribeTo(os); 367 *os << " whose effect ("; 368 effect_matcher_.DescribeTo(os); 369 *os << ") and control ("; 370 control_matcher_.DescribeTo(os); 371 *os << ")"; 372 } 373 374 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 375 return (NodeMatcher::MatchAndExplain(node, listener) && 376 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", 377 effect_matcher_, listener) && 378 PrintMatchAndExplain(NodeProperties::GetControlInput(node), 379 "control", control_matcher_, listener)); 380 } 381 382 private: 383 const Matcher<Node*> effect_matcher_; 384 const Matcher<Node*> control_matcher_; 385 }; 386 387 388 template <typename T> 389 class IsConstantMatcher final : public NodeMatcher { 390 public: 391 IsConstantMatcher(IrOpcode::Value opcode, const Matcher<T>& value_matcher) 392 : NodeMatcher(opcode), value_matcher_(value_matcher) {} 393 394 void DescribeTo(std::ostream* os) const final { 395 NodeMatcher::DescribeTo(os); 396 *os << " whose value ("; 397 value_matcher_.DescribeTo(os); 398 *os << ")"; 399 } 400 401 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 402 return (NodeMatcher::MatchAndExplain(node, listener) && 403 PrintMatchAndExplain(OpParameter<T>(node), "value", value_matcher_, 404 listener)); 405 } 406 407 private: 408 const Matcher<T> value_matcher_; 409 }; 410 411 412 class IsSelectMatcher final : public NodeMatcher { 413 public: 414 IsSelectMatcher(const Matcher<MachineRepresentation>& type_matcher, 415 const Matcher<Node*>& value0_matcher, 416 const Matcher<Node*>& value1_matcher, 417 const Matcher<Node*>& value2_matcher) 418 : NodeMatcher(IrOpcode::kSelect), 419 type_matcher_(type_matcher), 420 value0_matcher_(value0_matcher), 421 value1_matcher_(value1_matcher), 422 value2_matcher_(value2_matcher) {} 423 424 void DescribeTo(std::ostream* os) const final { 425 NodeMatcher::DescribeTo(os); 426 *os << " whose representation ("; 427 type_matcher_.DescribeTo(os); 428 *os << "), value0 ("; 429 value0_matcher_.DescribeTo(os); 430 *os << "), value1 ("; 431 value1_matcher_.DescribeTo(os); 432 *os << ") and value2 ("; 433 value2_matcher_.DescribeTo(os); 434 *os << ")"; 435 } 436 437 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 438 return ( 439 NodeMatcher::MatchAndExplain(node, listener) && 440 PrintMatchAndExplain(SelectParametersOf(node->op()).representation(), 441 "representation", type_matcher_, listener) && 442 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "value0", 443 value0_matcher_, listener) && 444 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "value1", 445 value1_matcher_, listener) && 446 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2), "value2", 447 value2_matcher_, listener)); 448 } 449 450 private: 451 const Matcher<MachineRepresentation> type_matcher_; 452 const Matcher<Node*> value0_matcher_; 453 const Matcher<Node*> value1_matcher_; 454 const Matcher<Node*> value2_matcher_; 455 }; 456 457 458 class IsPhiMatcher final : public NodeMatcher { 459 public: 460 IsPhiMatcher(const Matcher<MachineRepresentation>& type_matcher, 461 const Matcher<Node*>& value0_matcher, 462 const Matcher<Node*>& value1_matcher, 463 const Matcher<Node*>& control_matcher) 464 : NodeMatcher(IrOpcode::kPhi), 465 type_matcher_(type_matcher), 466 value0_matcher_(value0_matcher), 467 value1_matcher_(value1_matcher), 468 control_matcher_(control_matcher) {} 469 470 void DescribeTo(std::ostream* os) const final { 471 NodeMatcher::DescribeTo(os); 472 *os << " whose representation ("; 473 type_matcher_.DescribeTo(os); 474 *os << "), value0 ("; 475 value0_matcher_.DescribeTo(os); 476 *os << "), value1 ("; 477 value1_matcher_.DescribeTo(os); 478 *os << ") and control ("; 479 control_matcher_.DescribeTo(os); 480 *os << ")"; 481 } 482 483 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 484 return (NodeMatcher::MatchAndExplain(node, listener) && 485 PrintMatchAndExplain(PhiRepresentationOf(node->op()), 486 "representation", type_matcher_, listener) && 487 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), 488 "value0", value0_matcher_, listener) && 489 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), 490 "value1", value1_matcher_, listener) && 491 PrintMatchAndExplain(NodeProperties::GetControlInput(node), 492 "control", control_matcher_, listener)); 493 } 494 495 private: 496 const Matcher<MachineRepresentation> type_matcher_; 497 const Matcher<Node*> value0_matcher_; 498 const Matcher<Node*> value1_matcher_; 499 const Matcher<Node*> control_matcher_; 500 }; 501 502 503 class IsPhi2Matcher final : public NodeMatcher { 504 public: 505 IsPhi2Matcher(const Matcher<MachineRepresentation>& type_matcher, 506 const Matcher<Node*>& value0_matcher, 507 const Matcher<Node*>& value1_matcher, 508 const Matcher<Node*>& value2_matcher, 509 const Matcher<Node*>& control_matcher) 510 : NodeMatcher(IrOpcode::kPhi), 511 type_matcher_(type_matcher), 512 value0_matcher_(value0_matcher), 513 value1_matcher_(value1_matcher), 514 value2_matcher_(value2_matcher), 515 control_matcher_(control_matcher) {} 516 517 void DescribeTo(std::ostream* os) const final { 518 NodeMatcher::DescribeTo(os); 519 *os << " whose representation ("; 520 type_matcher_.DescribeTo(os); 521 *os << "), value0 ("; 522 value0_matcher_.DescribeTo(os); 523 *os << "), value1 ("; 524 value1_matcher_.DescribeTo(os); 525 *os << "), value2 ("; 526 value2_matcher_.DescribeTo(os); 527 *os << ") and control ("; 528 control_matcher_.DescribeTo(os); 529 *os << ")"; 530 } 531 532 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 533 return (NodeMatcher::MatchAndExplain(node, listener) && 534 PrintMatchAndExplain(PhiRepresentationOf(node->op()), 535 "representation", type_matcher_, listener) && 536 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), 537 "value0", value0_matcher_, listener) && 538 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), 539 "value1", value1_matcher_, listener) && 540 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2), 541 "value2", value2_matcher_, listener) && 542 PrintMatchAndExplain(NodeProperties::GetControlInput(node), 543 "control", control_matcher_, listener)); 544 } 545 546 private: 547 const Matcher<MachineRepresentation> type_matcher_; 548 const Matcher<Node*> value0_matcher_; 549 const Matcher<Node*> value1_matcher_; 550 const Matcher<Node*> value2_matcher_; 551 const Matcher<Node*> control_matcher_; 552 }; 553 554 555 class IsEffectPhiMatcher final : public NodeMatcher { 556 public: 557 IsEffectPhiMatcher(const Matcher<Node*>& effect0_matcher, 558 const Matcher<Node*>& effect1_matcher, 559 const Matcher<Node*>& control_matcher) 560 : NodeMatcher(IrOpcode::kEffectPhi), 561 effect0_matcher_(effect0_matcher), 562 effect1_matcher_(effect1_matcher), 563 control_matcher_(control_matcher) {} 564 565 void DescribeTo(std::ostream* os) const final { 566 NodeMatcher::DescribeTo(os); 567 *os << "), effect0 ("; 568 effect0_matcher_.DescribeTo(os); 569 *os << "), effect1 ("; 570 effect1_matcher_.DescribeTo(os); 571 *os << ") and control ("; 572 control_matcher_.DescribeTo(os); 573 *os << ")"; 574 } 575 576 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 577 return (NodeMatcher::MatchAndExplain(node, listener) && 578 PrintMatchAndExplain(NodeProperties::GetEffectInput(node, 0), 579 "effect0", effect0_matcher_, listener) && 580 PrintMatchAndExplain(NodeProperties::GetEffectInput(node, 1), 581 "effect1", effect1_matcher_, listener) && 582 PrintMatchAndExplain(NodeProperties::GetControlInput(node), 583 "control", control_matcher_, listener)); 584 } 585 586 private: 587 const Matcher<Node*> effect0_matcher_; 588 const Matcher<Node*> effect1_matcher_; 589 const Matcher<Node*> control_matcher_; 590 }; 591 592 593 class IsEffectSetMatcher final : public NodeMatcher { 594 public: 595 IsEffectSetMatcher(const Matcher<Node*>& effect0_matcher, 596 const Matcher<Node*>& effect1_matcher) 597 : NodeMatcher(IrOpcode::kEffectSet), 598 effect0_matcher_(effect0_matcher), 599 effect1_matcher_(effect1_matcher) {} 600 601 void DescribeTo(std::ostream* os) const final { 602 NodeMatcher::DescribeTo(os); 603 *os << "), effect0 ("; 604 effect0_matcher_.DescribeTo(os); 605 *os << ") and effect1 ("; 606 effect1_matcher_.DescribeTo(os); 607 *os << ")"; 608 } 609 610 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 611 if (!NodeMatcher::MatchAndExplain(node, listener)) return false; 612 613 Node* effect0 = NodeProperties::GetEffectInput(node, 0); 614 Node* effect1 = NodeProperties::GetEffectInput(node, 1); 615 616 { 617 // Try matching in the reverse order first. 618 StringMatchResultListener value_listener; 619 if (effect0_matcher_.MatchAndExplain(effect1, &value_listener) && 620 effect1_matcher_.MatchAndExplain(effect0, &value_listener)) { 621 return true; 622 } 623 } 624 625 return PrintMatchAndExplain(effect0, "effect0", effect0_matcher_, 626 listener) && 627 PrintMatchAndExplain(effect1, "effect1", effect1_matcher_, listener); 628 } 629 630 private: 631 const Matcher<Node*> effect0_matcher_; 632 const Matcher<Node*> effect1_matcher_; 633 }; 634 635 636 class IsProjectionMatcher final : public NodeMatcher { 637 public: 638 IsProjectionMatcher(const Matcher<size_t>& index_matcher, 639 const Matcher<Node*>& base_matcher) 640 : NodeMatcher(IrOpcode::kProjection), 641 index_matcher_(index_matcher), 642 base_matcher_(base_matcher) {} 643 644 void DescribeTo(std::ostream* os) const final { 645 NodeMatcher::DescribeTo(os); 646 *os << " whose index ("; 647 index_matcher_.DescribeTo(os); 648 *os << ") and base ("; 649 base_matcher_.DescribeTo(os); 650 *os << ")"; 651 } 652 653 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 654 return (NodeMatcher::MatchAndExplain(node, listener) && 655 PrintMatchAndExplain(OpParameter<size_t>(node), "index", 656 index_matcher_, listener) && 657 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base", 658 base_matcher_, listener)); 659 } 660 661 private: 662 const Matcher<size_t> index_matcher_; 663 const Matcher<Node*> base_matcher_; 664 }; 665 666 667 class IsCallMatcher final : public NodeMatcher { 668 public: 669 IsCallMatcher(const Matcher<const CallDescriptor*>& descriptor_matcher, 670 const std::vector<Matcher<Node*>>& value_matchers, 671 const Matcher<Node*>& effect_matcher, 672 const Matcher<Node*>& control_matcher) 673 : NodeMatcher(IrOpcode::kCall), 674 descriptor_matcher_(descriptor_matcher), 675 value_matchers_(value_matchers), 676 effect_matcher_(effect_matcher), 677 control_matcher_(control_matcher) {} 678 679 void DescribeTo(std::ostream* os) const final { 680 NodeMatcher::DescribeTo(os); 681 for (size_t i = 0; i < value_matchers_.size(); ++i) { 682 if (i == 0) { 683 *os << " whose value0 ("; 684 } else { 685 *os << "), value" << i << " ("; 686 } 687 value_matchers_[i].DescribeTo(os); 688 } 689 *os << "), effect ("; 690 effect_matcher_.DescribeTo(os); 691 *os << ") and control ("; 692 control_matcher_.DescribeTo(os); 693 *os << ")"; 694 } 695 696 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 697 if (!NodeMatcher::MatchAndExplain(node, listener) || 698 !PrintMatchAndExplain(OpParameter<const CallDescriptor*>(node), 699 "descriptor", descriptor_matcher_, listener)) { 700 return false; 701 } 702 for (size_t i = 0; i < value_matchers_.size(); ++i) { 703 std::ostringstream ost; 704 ost << "value" << i; 705 if (!PrintMatchAndExplain( 706 NodeProperties::GetValueInput(node, static_cast<int>(i)), 707 ost.str(), value_matchers_[i], listener)) { 708 return false; 709 } 710 } 711 Node* effect_node = nullptr; 712 Node* control_node = nullptr; 713 if (NodeProperties::FirstEffectIndex(node) < node->InputCount()) { 714 effect_node = NodeProperties::GetEffectInput(node); 715 } 716 if (NodeProperties::FirstControlIndex(node) < node->InputCount()) { 717 control_node = NodeProperties::GetControlInput(node); 718 } 719 return (PrintMatchAndExplain(effect_node, "effect", effect_matcher_, 720 listener) && 721 PrintMatchAndExplain(control_node, "control", control_matcher_, 722 listener)); 723 } 724 725 private: 726 const Matcher<const CallDescriptor*> descriptor_matcher_; 727 const std::vector<Matcher<Node*>> value_matchers_; 728 const Matcher<Node*> effect_matcher_; 729 const Matcher<Node*> control_matcher_; 730 }; 731 732 733 class IsTailCallMatcher final : public NodeMatcher { 734 public: 735 IsTailCallMatcher(const Matcher<CallDescriptor const*>& descriptor_matcher, 736 const std::vector<Matcher<Node*>>& value_matchers, 737 const Matcher<Node*>& effect_matcher, 738 const Matcher<Node*>& control_matcher) 739 : NodeMatcher(IrOpcode::kTailCall), 740 descriptor_matcher_(descriptor_matcher), 741 value_matchers_(value_matchers), 742 effect_matcher_(effect_matcher), 743 control_matcher_(control_matcher) {} 744 745 void DescribeTo(std::ostream* os) const final { 746 NodeMatcher::DescribeTo(os); 747 for (size_t i = 0; i < value_matchers_.size(); ++i) { 748 if (i == 0) { 749 *os << " whose value0 ("; 750 } else { 751 *os << "), value" << i << " ("; 752 } 753 value_matchers_[i].DescribeTo(os); 754 } 755 *os << "), effect ("; 756 effect_matcher_.DescribeTo(os); 757 *os << ") and control ("; 758 control_matcher_.DescribeTo(os); 759 *os << ")"; 760 } 761 762 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 763 if (!NodeMatcher::MatchAndExplain(node, listener) || 764 !PrintMatchAndExplain(OpParameter<CallDescriptor const*>(node), 765 "descriptor", descriptor_matcher_, listener)) { 766 return false; 767 } 768 for (size_t i = 0; i < value_matchers_.size(); ++i) { 769 std::ostringstream ost; 770 ost << "value" << i; 771 if (!PrintMatchAndExplain( 772 NodeProperties::GetValueInput(node, static_cast<int>(i)), 773 ost.str(), value_matchers_[i], listener)) { 774 return false; 775 } 776 } 777 Node* effect_node = nullptr; 778 Node* control_node = nullptr; 779 if (NodeProperties::FirstEffectIndex(node) < node->InputCount()) { 780 effect_node = NodeProperties::GetEffectInput(node); 781 } 782 if (NodeProperties::FirstControlIndex(node) < node->InputCount()) { 783 control_node = NodeProperties::GetControlInput(node); 784 } 785 return (PrintMatchAndExplain(effect_node, "effect", effect_matcher_, 786 listener) && 787 PrintMatchAndExplain(control_node, "control", control_matcher_, 788 listener)); 789 } 790 791 private: 792 const Matcher<CallDescriptor const*> descriptor_matcher_; 793 const std::vector<Matcher<Node*>> value_matchers_; 794 const Matcher<Node*> effect_matcher_; 795 const Matcher<Node*> control_matcher_; 796 }; 797 798 799 class IsReferenceEqualMatcher final : public NodeMatcher { 800 public: 801 IsReferenceEqualMatcher(const Matcher<Type*>& type_matcher, 802 const Matcher<Node*>& lhs_matcher, 803 const Matcher<Node*>& rhs_matcher) 804 : NodeMatcher(IrOpcode::kReferenceEqual), 805 type_matcher_(type_matcher), 806 lhs_matcher_(lhs_matcher), 807 rhs_matcher_(rhs_matcher) {} 808 809 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 810 return (NodeMatcher::MatchAndExplain(node, listener) && 811 // TODO(bmeurer): The type parameter is currently ignored. 812 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "lhs", 813 lhs_matcher_, listener) && 814 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "rhs", 815 rhs_matcher_, listener)); 816 } 817 818 private: 819 const Matcher<Type*> type_matcher_; 820 const Matcher<Node*> lhs_matcher_; 821 const Matcher<Node*> rhs_matcher_; 822 }; 823 824 825 class IsAllocateMatcher final : public NodeMatcher { 826 public: 827 IsAllocateMatcher(const Matcher<Node*>& size_matcher, 828 const Matcher<Node*>& effect_matcher, 829 const Matcher<Node*>& control_matcher) 830 : NodeMatcher(IrOpcode::kAllocate), 831 size_matcher_(size_matcher), 832 effect_matcher_(effect_matcher), 833 control_matcher_(control_matcher) {} 834 835 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 836 return (NodeMatcher::MatchAndExplain(node, listener) && 837 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "size", 838 size_matcher_, listener) && 839 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", 840 effect_matcher_, listener) && 841 PrintMatchAndExplain(NodeProperties::GetControlInput(node), 842 "control", control_matcher_, listener)); 843 } 844 845 private: 846 const Matcher<Node*> size_matcher_; 847 const Matcher<Node*> effect_matcher_; 848 const Matcher<Node*> control_matcher_; 849 }; 850 851 852 class IsLoadFieldMatcher final : public NodeMatcher { 853 public: 854 IsLoadFieldMatcher(const Matcher<FieldAccess>& access_matcher, 855 const Matcher<Node*>& base_matcher, 856 const Matcher<Node*>& effect_matcher, 857 const Matcher<Node*>& control_matcher) 858 : NodeMatcher(IrOpcode::kLoadField), 859 access_matcher_(access_matcher), 860 base_matcher_(base_matcher), 861 effect_matcher_(effect_matcher), 862 control_matcher_(control_matcher) {} 863 864 void DescribeTo(std::ostream* os) const final { 865 NodeMatcher::DescribeTo(os); 866 *os << " whose access ("; 867 access_matcher_.DescribeTo(os); 868 *os << "), base ("; 869 base_matcher_.DescribeTo(os); 870 *os << "), effect ("; 871 effect_matcher_.DescribeTo(os); 872 *os << ") and control ("; 873 control_matcher_.DescribeTo(os); 874 *os << ")"; 875 } 876 877 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 878 return (NodeMatcher::MatchAndExplain(node, listener) && 879 PrintMatchAndExplain(OpParameter<FieldAccess>(node), "access", 880 access_matcher_, listener) && 881 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base", 882 base_matcher_, listener) && 883 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", 884 effect_matcher_, listener) && 885 PrintMatchAndExplain(NodeProperties::GetControlInput(node), 886 "control", control_matcher_, listener)); 887 } 888 889 private: 890 const Matcher<FieldAccess> access_matcher_; 891 const Matcher<Node*> base_matcher_; 892 const Matcher<Node*> effect_matcher_; 893 const Matcher<Node*> control_matcher_; 894 }; 895 896 897 class IsStoreFieldMatcher final : public NodeMatcher { 898 public: 899 IsStoreFieldMatcher(const Matcher<FieldAccess>& access_matcher, 900 const Matcher<Node*>& base_matcher, 901 const Matcher<Node*>& value_matcher, 902 const Matcher<Node*>& effect_matcher, 903 const Matcher<Node*>& control_matcher) 904 : NodeMatcher(IrOpcode::kStoreField), 905 access_matcher_(access_matcher), 906 base_matcher_(base_matcher), 907 value_matcher_(value_matcher), 908 effect_matcher_(effect_matcher), 909 control_matcher_(control_matcher) {} 910 911 void DescribeTo(std::ostream* os) const final { 912 NodeMatcher::DescribeTo(os); 913 *os << " whose access ("; 914 access_matcher_.DescribeTo(os); 915 *os << "), base ("; 916 base_matcher_.DescribeTo(os); 917 *os << "), value ("; 918 value_matcher_.DescribeTo(os); 919 *os << "), effect ("; 920 effect_matcher_.DescribeTo(os); 921 *os << ") and control ("; 922 control_matcher_.DescribeTo(os); 923 *os << ")"; 924 } 925 926 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 927 return (NodeMatcher::MatchAndExplain(node, listener) && 928 PrintMatchAndExplain(OpParameter<FieldAccess>(node), "access", 929 access_matcher_, listener) && 930 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base", 931 base_matcher_, listener) && 932 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), 933 "value", value_matcher_, listener) && 934 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", 935 effect_matcher_, listener) && 936 PrintMatchAndExplain(NodeProperties::GetControlInput(node), 937 "control", control_matcher_, listener)); 938 } 939 940 private: 941 const Matcher<FieldAccess> access_matcher_; 942 const Matcher<Node*> base_matcher_; 943 const Matcher<Node*> value_matcher_; 944 const Matcher<Node*> effect_matcher_; 945 const Matcher<Node*> control_matcher_; 946 }; 947 948 949 class IsLoadBufferMatcher final : public NodeMatcher { 950 public: 951 IsLoadBufferMatcher(const Matcher<BufferAccess>& access_matcher, 952 const Matcher<Node*>& buffer_matcher, 953 const Matcher<Node*>& offset_matcher, 954 const Matcher<Node*>& length_matcher, 955 const Matcher<Node*>& effect_matcher, 956 const Matcher<Node*>& control_matcher) 957 : NodeMatcher(IrOpcode::kLoadBuffer), 958 access_matcher_(access_matcher), 959 buffer_matcher_(buffer_matcher), 960 offset_matcher_(offset_matcher), 961 length_matcher_(length_matcher), 962 effect_matcher_(effect_matcher), 963 control_matcher_(control_matcher) {} 964 965 void DescribeTo(std::ostream* os) const final { 966 NodeMatcher::DescribeTo(os); 967 *os << " whose access ("; 968 access_matcher_.DescribeTo(os); 969 *os << "), buffer ("; 970 buffer_matcher_.DescribeTo(os); 971 *os << "), offset ("; 972 offset_matcher_.DescribeTo(os); 973 *os << "), length ("; 974 length_matcher_.DescribeTo(os); 975 *os << "), effect ("; 976 effect_matcher_.DescribeTo(os); 977 *os << ") and control ("; 978 control_matcher_.DescribeTo(os); 979 *os << ")"; 980 } 981 982 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 983 return (NodeMatcher::MatchAndExplain(node, listener) && 984 PrintMatchAndExplain(BufferAccessOf(node->op()), "access", 985 access_matcher_, listener) && 986 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), 987 "buffer", buffer_matcher_, listener) && 988 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), 989 "offset", offset_matcher_, listener) && 990 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2), 991 "length", length_matcher_, listener) && 992 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", 993 effect_matcher_, listener) && 994 PrintMatchAndExplain(NodeProperties::GetControlInput(node), 995 "control", control_matcher_, listener)); 996 } 997 998 private: 999 const Matcher<BufferAccess> access_matcher_; 1000 const Matcher<Node*> buffer_matcher_; 1001 const Matcher<Node*> offset_matcher_; 1002 const Matcher<Node*> length_matcher_; 1003 const Matcher<Node*> effect_matcher_; 1004 const Matcher<Node*> control_matcher_; 1005 }; 1006 1007 1008 class IsStoreBufferMatcher final : public NodeMatcher { 1009 public: 1010 IsStoreBufferMatcher(const Matcher<BufferAccess>& access_matcher, 1011 const Matcher<Node*>& buffer_matcher, 1012 const Matcher<Node*>& offset_matcher, 1013 const Matcher<Node*>& length_matcher, 1014 const Matcher<Node*>& value_matcher, 1015 const Matcher<Node*>& effect_matcher, 1016 const Matcher<Node*>& control_matcher) 1017 : NodeMatcher(IrOpcode::kStoreBuffer), 1018 access_matcher_(access_matcher), 1019 buffer_matcher_(buffer_matcher), 1020 offset_matcher_(offset_matcher), 1021 length_matcher_(length_matcher), 1022 value_matcher_(value_matcher), 1023 effect_matcher_(effect_matcher), 1024 control_matcher_(control_matcher) {} 1025 1026 void DescribeTo(std::ostream* os) const final { 1027 NodeMatcher::DescribeTo(os); 1028 *os << " whose access ("; 1029 access_matcher_.DescribeTo(os); 1030 *os << "), buffer ("; 1031 buffer_matcher_.DescribeTo(os); 1032 *os << "), offset ("; 1033 offset_matcher_.DescribeTo(os); 1034 *os << "), length ("; 1035 length_matcher_.DescribeTo(os); 1036 *os << "), value ("; 1037 value_matcher_.DescribeTo(os); 1038 *os << "), effect ("; 1039 effect_matcher_.DescribeTo(os); 1040 *os << ") and control ("; 1041 control_matcher_.DescribeTo(os); 1042 *os << ")"; 1043 } 1044 1045 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 1046 return (NodeMatcher::MatchAndExplain(node, listener) && 1047 PrintMatchAndExplain(BufferAccessOf(node->op()), "access", 1048 access_matcher_, listener) && 1049 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), 1050 "buffer", buffer_matcher_, listener) && 1051 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), 1052 "offset", offset_matcher_, listener) && 1053 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2), 1054 "length", length_matcher_, listener) && 1055 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 3), 1056 "value", value_matcher_, listener) && 1057 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", 1058 effect_matcher_, listener) && 1059 PrintMatchAndExplain(NodeProperties::GetControlInput(node), 1060 "control", control_matcher_, listener)); 1061 } 1062 1063 private: 1064 const Matcher<BufferAccess> access_matcher_; 1065 const Matcher<Node*> buffer_matcher_; 1066 const Matcher<Node*> offset_matcher_; 1067 const Matcher<Node*> length_matcher_; 1068 const Matcher<Node*> value_matcher_; 1069 const Matcher<Node*> effect_matcher_; 1070 const Matcher<Node*> control_matcher_; 1071 }; 1072 1073 1074 class IsLoadElementMatcher final : public NodeMatcher { 1075 public: 1076 IsLoadElementMatcher(const Matcher<ElementAccess>& access_matcher, 1077 const Matcher<Node*>& base_matcher, 1078 const Matcher<Node*>& index_matcher, 1079 const Matcher<Node*>& effect_matcher, 1080 const Matcher<Node*>& control_matcher) 1081 : NodeMatcher(IrOpcode::kLoadElement), 1082 access_matcher_(access_matcher), 1083 base_matcher_(base_matcher), 1084 index_matcher_(index_matcher), 1085 effect_matcher_(effect_matcher), 1086 control_matcher_(control_matcher) {} 1087 1088 void DescribeTo(std::ostream* os) const final { 1089 NodeMatcher::DescribeTo(os); 1090 *os << " whose access ("; 1091 access_matcher_.DescribeTo(os); 1092 *os << "), base ("; 1093 base_matcher_.DescribeTo(os); 1094 *os << "), index ("; 1095 index_matcher_.DescribeTo(os); 1096 *os << "), effect ("; 1097 effect_matcher_.DescribeTo(os); 1098 *os << ") and control ("; 1099 control_matcher_.DescribeTo(os); 1100 *os << ")"; 1101 } 1102 1103 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 1104 return (NodeMatcher::MatchAndExplain(node, listener) && 1105 PrintMatchAndExplain(OpParameter<ElementAccess>(node), "access", 1106 access_matcher_, listener) && 1107 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base", 1108 base_matcher_, listener) && 1109 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), 1110 "index", index_matcher_, listener) && 1111 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", 1112 effect_matcher_, listener) && 1113 PrintMatchAndExplain(NodeProperties::GetControlInput(node), 1114 "control", control_matcher_, listener)); 1115 } 1116 1117 private: 1118 const Matcher<ElementAccess> access_matcher_; 1119 const Matcher<Node*> base_matcher_; 1120 const Matcher<Node*> index_matcher_; 1121 const Matcher<Node*> effect_matcher_; 1122 const Matcher<Node*> control_matcher_; 1123 }; 1124 1125 1126 class IsStoreElementMatcher final : public NodeMatcher { 1127 public: 1128 IsStoreElementMatcher(const Matcher<ElementAccess>& access_matcher, 1129 const Matcher<Node*>& base_matcher, 1130 const Matcher<Node*>& index_matcher, 1131 const Matcher<Node*>& value_matcher, 1132 const Matcher<Node*>& effect_matcher, 1133 const Matcher<Node*>& control_matcher) 1134 : NodeMatcher(IrOpcode::kStoreElement), 1135 access_matcher_(access_matcher), 1136 base_matcher_(base_matcher), 1137 index_matcher_(index_matcher), 1138 value_matcher_(value_matcher), 1139 effect_matcher_(effect_matcher), 1140 control_matcher_(control_matcher) {} 1141 1142 void DescribeTo(std::ostream* os) const final { 1143 NodeMatcher::DescribeTo(os); 1144 *os << " whose access ("; 1145 access_matcher_.DescribeTo(os); 1146 *os << "), base ("; 1147 base_matcher_.DescribeTo(os); 1148 *os << "), index ("; 1149 index_matcher_.DescribeTo(os); 1150 *os << "), value ("; 1151 value_matcher_.DescribeTo(os); 1152 *os << "), effect ("; 1153 effect_matcher_.DescribeTo(os); 1154 *os << ") and control ("; 1155 control_matcher_.DescribeTo(os); 1156 *os << ")"; 1157 } 1158 1159 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 1160 return (NodeMatcher::MatchAndExplain(node, listener) && 1161 PrintMatchAndExplain(OpParameter<ElementAccess>(node), "access", 1162 access_matcher_, listener) && 1163 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base", 1164 base_matcher_, listener) && 1165 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), 1166 "index", index_matcher_, listener) && 1167 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2), 1168 "value", value_matcher_, listener) && 1169 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", 1170 effect_matcher_, listener) && 1171 PrintMatchAndExplain(NodeProperties::GetControlInput(node), 1172 "control", control_matcher_, listener)); 1173 } 1174 1175 private: 1176 const Matcher<ElementAccess> access_matcher_; 1177 const Matcher<Node*> base_matcher_; 1178 const Matcher<Node*> index_matcher_; 1179 const Matcher<Node*> value_matcher_; 1180 const Matcher<Node*> effect_matcher_; 1181 const Matcher<Node*> control_matcher_; 1182 }; 1183 1184 1185 class IsLoadMatcher final : public NodeMatcher { 1186 public: 1187 IsLoadMatcher(const Matcher<LoadRepresentation>& rep_matcher, 1188 const Matcher<Node*>& base_matcher, 1189 const Matcher<Node*>& index_matcher, 1190 const Matcher<Node*>& effect_matcher, 1191 const Matcher<Node*>& control_matcher) 1192 : NodeMatcher(IrOpcode::kLoad), 1193 rep_matcher_(rep_matcher), 1194 base_matcher_(base_matcher), 1195 index_matcher_(index_matcher), 1196 effect_matcher_(effect_matcher), 1197 control_matcher_(control_matcher) {} 1198 1199 void DescribeTo(std::ostream* os) const final { 1200 NodeMatcher::DescribeTo(os); 1201 *os << " whose rep ("; 1202 rep_matcher_.DescribeTo(os); 1203 *os << "), base ("; 1204 base_matcher_.DescribeTo(os); 1205 *os << "), index ("; 1206 index_matcher_.DescribeTo(os); 1207 *os << "), effect ("; 1208 effect_matcher_.DescribeTo(os); 1209 *os << ") and control ("; 1210 control_matcher_.DescribeTo(os); 1211 *os << ")"; 1212 } 1213 1214 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 1215 Node* effect_node = nullptr; 1216 Node* control_node = nullptr; 1217 if (NodeProperties::FirstEffectIndex(node) < node->InputCount()) { 1218 effect_node = NodeProperties::GetEffectInput(node); 1219 } 1220 if (NodeProperties::FirstControlIndex(node) < node->InputCount()) { 1221 control_node = NodeProperties::GetControlInput(node); 1222 } 1223 return (NodeMatcher::MatchAndExplain(node, listener) && 1224 PrintMatchAndExplain(OpParameter<LoadRepresentation>(node), "rep", 1225 rep_matcher_, listener) && 1226 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base", 1227 base_matcher_, listener) && 1228 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), 1229 "index", index_matcher_, listener) && 1230 PrintMatchAndExplain(effect_node, "effect", effect_matcher_, 1231 listener) && 1232 PrintMatchAndExplain(control_node, "control", control_matcher_, 1233 listener)); 1234 } 1235 1236 private: 1237 const Matcher<LoadRepresentation> rep_matcher_; 1238 const Matcher<Node*> base_matcher_; 1239 const Matcher<Node*> index_matcher_; 1240 const Matcher<Node*> effect_matcher_; 1241 const Matcher<Node*> control_matcher_; 1242 }; 1243 1244 1245 class IsStoreMatcher final : public NodeMatcher { 1246 public: 1247 IsStoreMatcher(const Matcher<StoreRepresentation>& rep_matcher, 1248 const Matcher<Node*>& base_matcher, 1249 const Matcher<Node*>& index_matcher, 1250 const Matcher<Node*>& value_matcher, 1251 const Matcher<Node*>& effect_matcher, 1252 const Matcher<Node*>& control_matcher) 1253 : NodeMatcher(IrOpcode::kStore), 1254 rep_matcher_(rep_matcher), 1255 base_matcher_(base_matcher), 1256 index_matcher_(index_matcher), 1257 value_matcher_(value_matcher), 1258 effect_matcher_(effect_matcher), 1259 control_matcher_(control_matcher) {} 1260 1261 void DescribeTo(std::ostream* os) const final { 1262 NodeMatcher::DescribeTo(os); 1263 *os << " whose rep ("; 1264 rep_matcher_.DescribeTo(os); 1265 *os << "), base ("; 1266 base_matcher_.DescribeTo(os); 1267 *os << "), index ("; 1268 index_matcher_.DescribeTo(os); 1269 *os << "), value ("; 1270 value_matcher_.DescribeTo(os); 1271 *os << "), effect ("; 1272 effect_matcher_.DescribeTo(os); 1273 *os << ") and control ("; 1274 control_matcher_.DescribeTo(os); 1275 *os << ")"; 1276 } 1277 1278 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 1279 Node* effect_node = nullptr; 1280 Node* control_node = nullptr; 1281 if (NodeProperties::FirstEffectIndex(node) < node->InputCount()) { 1282 effect_node = NodeProperties::GetEffectInput(node); 1283 } 1284 if (NodeProperties::FirstControlIndex(node) < node->InputCount()) { 1285 control_node = NodeProperties::GetControlInput(node); 1286 } 1287 return (NodeMatcher::MatchAndExplain(node, listener) && 1288 PrintMatchAndExplain(OpParameter<StoreRepresentation>(node), "rep", 1289 rep_matcher_, listener) && 1290 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base", 1291 base_matcher_, listener) && 1292 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), 1293 "index", index_matcher_, listener) && 1294 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2), 1295 "value", value_matcher_, listener) && 1296 PrintMatchAndExplain(effect_node, "effect", effect_matcher_, 1297 listener) && 1298 PrintMatchAndExplain(control_node, "control", control_matcher_, 1299 listener)); 1300 } 1301 1302 private: 1303 const Matcher<StoreRepresentation> rep_matcher_; 1304 const Matcher<Node*> base_matcher_; 1305 const Matcher<Node*> index_matcher_; 1306 const Matcher<Node*> value_matcher_; 1307 const Matcher<Node*> effect_matcher_; 1308 const Matcher<Node*> control_matcher_; 1309 }; 1310 1311 1312 class IsToNumberMatcher final : public NodeMatcher { 1313 public: 1314 IsToNumberMatcher(const Matcher<Node*>& base_matcher, 1315 const Matcher<Node*>& context_matcher, 1316 const Matcher<Node*>& effect_matcher, 1317 const Matcher<Node*>& control_matcher) 1318 : NodeMatcher(IrOpcode::kJSToNumber), 1319 base_matcher_(base_matcher), 1320 context_matcher_(context_matcher), 1321 effect_matcher_(effect_matcher), 1322 control_matcher_(control_matcher) {} 1323 1324 void DescribeTo(std::ostream* os) const final { 1325 NodeMatcher::DescribeTo(os); 1326 *os << " whose base ("; 1327 base_matcher_.DescribeTo(os); 1328 *os << "), context ("; 1329 context_matcher_.DescribeTo(os); 1330 *os << "), effect ("; 1331 effect_matcher_.DescribeTo(os); 1332 *os << ") and control ("; 1333 control_matcher_.DescribeTo(os); 1334 *os << ")"; 1335 } 1336 1337 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 1338 return (NodeMatcher::MatchAndExplain(node, listener) && 1339 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base", 1340 base_matcher_, listener) && 1341 PrintMatchAndExplain(NodeProperties::GetContextInput(node), 1342 "context", context_matcher_, listener) && 1343 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", 1344 effect_matcher_, listener) && 1345 PrintMatchAndExplain(NodeProperties::GetControlInput(node), 1346 "control", control_matcher_, listener)); 1347 } 1348 1349 private: 1350 const Matcher<Node*> base_matcher_; 1351 const Matcher<Node*> context_matcher_; 1352 const Matcher<Node*> effect_matcher_; 1353 const Matcher<Node*> control_matcher_; 1354 }; 1355 1356 1357 class IsLoadContextMatcher final : public NodeMatcher { 1358 public: 1359 IsLoadContextMatcher(const Matcher<ContextAccess>& access_matcher, 1360 const Matcher<Node*>& context_matcher) 1361 : NodeMatcher(IrOpcode::kJSLoadContext), 1362 access_matcher_(access_matcher), 1363 context_matcher_(context_matcher) {} 1364 1365 void DescribeTo(std::ostream* os) const final { 1366 NodeMatcher::DescribeTo(os); 1367 *os << " whose access ("; 1368 access_matcher_.DescribeTo(os); 1369 *os << ") and context ("; 1370 context_matcher_.DescribeTo(os); 1371 *os << ")"; 1372 } 1373 1374 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 1375 return (NodeMatcher::MatchAndExplain(node, listener) && 1376 PrintMatchAndExplain(OpParameter<ContextAccess>(node), "access", 1377 access_matcher_, listener) && 1378 PrintMatchAndExplain(NodeProperties::GetContextInput(node), 1379 "context", context_matcher_, listener)); 1380 } 1381 1382 private: 1383 const Matcher<ContextAccess> access_matcher_; 1384 const Matcher<Node*> context_matcher_; 1385 }; 1386 1387 1388 class IsBinopMatcher final : public NodeMatcher { 1389 public: 1390 IsBinopMatcher(IrOpcode::Value opcode, const Matcher<Node*>& lhs_matcher, 1391 const Matcher<Node*>& rhs_matcher) 1392 : NodeMatcher(opcode), 1393 lhs_matcher_(lhs_matcher), 1394 rhs_matcher_(rhs_matcher) {} 1395 1396 void DescribeTo(std::ostream* os) const final { 1397 NodeMatcher::DescribeTo(os); 1398 *os << " whose lhs ("; 1399 lhs_matcher_.DescribeTo(os); 1400 *os << ") and rhs ("; 1401 rhs_matcher_.DescribeTo(os); 1402 *os << ")"; 1403 } 1404 1405 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 1406 return (NodeMatcher::MatchAndExplain(node, listener) && 1407 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "lhs", 1408 lhs_matcher_, listener) && 1409 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "rhs", 1410 rhs_matcher_, listener)); 1411 } 1412 1413 private: 1414 const Matcher<Node*> lhs_matcher_; 1415 const Matcher<Node*> rhs_matcher_; 1416 }; 1417 1418 1419 class IsUnopMatcher final : public NodeMatcher { 1420 public: 1421 IsUnopMatcher(IrOpcode::Value opcode, const Matcher<Node*>& input_matcher) 1422 : NodeMatcher(opcode), input_matcher_(input_matcher) {} 1423 1424 void DescribeTo(std::ostream* os) const final { 1425 NodeMatcher::DescribeTo(os); 1426 *os << " whose input ("; 1427 input_matcher_.DescribeTo(os); 1428 *os << ")"; 1429 } 1430 1431 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 1432 return (NodeMatcher::MatchAndExplain(node, listener) && 1433 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), 1434 "input", input_matcher_, listener)); 1435 } 1436 1437 private: 1438 const Matcher<Node*> input_matcher_; 1439 }; 1440 1441 1442 class IsParameterMatcher final : public NodeMatcher { 1443 public: 1444 explicit IsParameterMatcher(const Matcher<int>& index_matcher) 1445 : NodeMatcher(IrOpcode::kParameter), index_matcher_(index_matcher) {} 1446 1447 void DescribeTo(std::ostream* os) const override { 1448 *os << "is a Parameter node with index("; 1449 index_matcher_.DescribeTo(os); 1450 *os << ")"; 1451 } 1452 1453 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 1454 return (NodeMatcher::MatchAndExplain(node, listener) && 1455 PrintMatchAndExplain(ParameterIndexOf(node->op()), "index", 1456 index_matcher_, listener)); 1457 } 1458 1459 private: 1460 const Matcher<int> index_matcher_; 1461 }; 1462 1463 } // namespace 1464 1465 1466 Matcher<Node*> IsDead() { 1467 return MakeMatcher(new NodeMatcher(IrOpcode::kDead)); 1468 } 1469 1470 1471 Matcher<Node*> IsEnd(const Matcher<Node*>& control0_matcher) { 1472 return MakeMatcher(new IsControl1Matcher(IrOpcode::kEnd, control0_matcher)); 1473 } 1474 1475 1476 Matcher<Node*> IsEnd(const Matcher<Node*>& control0_matcher, 1477 const Matcher<Node*>& control1_matcher) { 1478 return MakeMatcher(new IsControl2Matcher(IrOpcode::kEnd, control0_matcher, 1479 control1_matcher)); 1480 } 1481 1482 1483 Matcher<Node*> IsEnd(const Matcher<Node*>& control0_matcher, 1484 const Matcher<Node*>& control1_matcher, 1485 const Matcher<Node*>& control2_matcher) { 1486 return MakeMatcher(new IsControl3Matcher(IrOpcode::kEnd, control0_matcher, 1487 control1_matcher, control2_matcher)); 1488 } 1489 1490 1491 Matcher<Node*> IsBranch(const Matcher<Node*>& value_matcher, 1492 const Matcher<Node*>& control_matcher) { 1493 return MakeMatcher(new IsBranchMatcher(value_matcher, control_matcher)); 1494 } 1495 1496 1497 Matcher<Node*> IsMerge(const Matcher<Node*>& control0_matcher, 1498 const Matcher<Node*>& control1_matcher) { 1499 return MakeMatcher(new IsControl2Matcher(IrOpcode::kMerge, control0_matcher, 1500 control1_matcher)); 1501 } 1502 1503 1504 Matcher<Node*> IsMerge(const Matcher<Node*>& control0_matcher, 1505 const Matcher<Node*>& control1_matcher, 1506 const Matcher<Node*>& control2_matcher) { 1507 return MakeMatcher(new IsControl3Matcher(IrOpcode::kMerge, control0_matcher, 1508 control1_matcher, control2_matcher)); 1509 } 1510 1511 1512 Matcher<Node*> IsLoop(const Matcher<Node*>& control0_matcher, 1513 const Matcher<Node*>& control1_matcher) { 1514 return MakeMatcher(new IsControl2Matcher(IrOpcode::kLoop, control0_matcher, 1515 control1_matcher)); 1516 } 1517 1518 1519 Matcher<Node*> IsLoop(const Matcher<Node*>& control0_matcher, 1520 const Matcher<Node*>& control1_matcher, 1521 const Matcher<Node*>& control2_matcher) { 1522 return MakeMatcher(new IsControl3Matcher(IrOpcode::kLoop, control0_matcher, 1523 control1_matcher, control2_matcher)); 1524 } 1525 1526 1527 Matcher<Node*> IsIfTrue(const Matcher<Node*>& control_matcher) { 1528 return MakeMatcher(new IsControl1Matcher(IrOpcode::kIfTrue, control_matcher)); 1529 } 1530 1531 1532 Matcher<Node*> IsIfFalse(const Matcher<Node*>& control_matcher) { 1533 return MakeMatcher( 1534 new IsControl1Matcher(IrOpcode::kIfFalse, control_matcher)); 1535 } 1536 1537 1538 Matcher<Node*> IsIfSuccess(const Matcher<Node*>& control_matcher) { 1539 return MakeMatcher( 1540 new IsControl1Matcher(IrOpcode::kIfSuccess, control_matcher)); 1541 } 1542 1543 1544 Matcher<Node*> IsSwitch(const Matcher<Node*>& value_matcher, 1545 const Matcher<Node*>& control_matcher) { 1546 return MakeMatcher(new IsSwitchMatcher(value_matcher, control_matcher)); 1547 } 1548 1549 1550 Matcher<Node*> IsIfValue(const Matcher<int32_t>& value_matcher, 1551 const Matcher<Node*>& control_matcher) { 1552 return MakeMatcher(new IsIfValueMatcher(value_matcher, control_matcher)); 1553 } 1554 1555 1556 Matcher<Node*> IsIfDefault(const Matcher<Node*>& control_matcher) { 1557 return MakeMatcher( 1558 new IsControl1Matcher(IrOpcode::kIfDefault, control_matcher)); 1559 } 1560 1561 1562 Matcher<Node*> IsBeginRegion(const Matcher<Node*>& effect_matcher) { 1563 return MakeMatcher(new IsBeginRegionMatcher(effect_matcher)); 1564 } 1565 1566 1567 Matcher<Node*> IsFinishRegion(const Matcher<Node*>& value_matcher, 1568 const Matcher<Node*>& effect_matcher) { 1569 return MakeMatcher(new IsFinishRegionMatcher(value_matcher, effect_matcher)); 1570 } 1571 1572 1573 Matcher<Node*> IsReturn(const Matcher<Node*>& value_matcher, 1574 const Matcher<Node*>& effect_matcher, 1575 const Matcher<Node*>& control_matcher) { 1576 return MakeMatcher( 1577 new IsReturnMatcher(value_matcher, effect_matcher, control_matcher)); 1578 } 1579 1580 1581 Matcher<Node*> IsTerminate(const Matcher<Node*>& effect_matcher, 1582 const Matcher<Node*>& control_matcher) { 1583 return MakeMatcher(new IsTerminateMatcher(effect_matcher, control_matcher)); 1584 } 1585 1586 1587 Matcher<Node*> IsExternalConstant( 1588 const Matcher<ExternalReference>& value_matcher) { 1589 return MakeMatcher(new IsConstantMatcher<ExternalReference>( 1590 IrOpcode::kExternalConstant, value_matcher)); 1591 } 1592 1593 1594 Matcher<Node*> IsHeapConstant(Handle<HeapObject> value) { 1595 return MakeMatcher(new IsConstantMatcher<Handle<HeapObject>>( 1596 IrOpcode::kHeapConstant, value)); 1597 } 1598 1599 1600 Matcher<Node*> IsInt32Constant(const Matcher<int32_t>& value_matcher) { 1601 return MakeMatcher( 1602 new IsConstantMatcher<int32_t>(IrOpcode::kInt32Constant, value_matcher)); 1603 } 1604 1605 1606 Matcher<Node*> IsInt64Constant(const Matcher<int64_t>& value_matcher) { 1607 return MakeMatcher( 1608 new IsConstantMatcher<int64_t>(IrOpcode::kInt64Constant, value_matcher)); 1609 } 1610 1611 1612 Matcher<Node*> IsFloat32Constant(const Matcher<float>& value_matcher) { 1613 return MakeMatcher( 1614 new IsConstantMatcher<float>(IrOpcode::kFloat32Constant, value_matcher)); 1615 } 1616 1617 1618 Matcher<Node*> IsFloat64Constant(const Matcher<double>& value_matcher) { 1619 return MakeMatcher( 1620 new IsConstantMatcher<double>(IrOpcode::kFloat64Constant, value_matcher)); 1621 } 1622 1623 1624 Matcher<Node*> IsNumberConstant(const Matcher<double>& value_matcher) { 1625 return MakeMatcher( 1626 new IsConstantMatcher<double>(IrOpcode::kNumberConstant, value_matcher)); 1627 } 1628 1629 1630 Matcher<Node*> IsSelect(const Matcher<MachineRepresentation>& type_matcher, 1631 const Matcher<Node*>& value0_matcher, 1632 const Matcher<Node*>& value1_matcher, 1633 const Matcher<Node*>& value2_matcher) { 1634 return MakeMatcher(new IsSelectMatcher(type_matcher, value0_matcher, 1635 value1_matcher, value2_matcher)); 1636 } 1637 1638 1639 Matcher<Node*> IsPhi(const Matcher<MachineRepresentation>& type_matcher, 1640 const Matcher<Node*>& value0_matcher, 1641 const Matcher<Node*>& value1_matcher, 1642 const Matcher<Node*>& merge_matcher) { 1643 return MakeMatcher(new IsPhiMatcher(type_matcher, value0_matcher, 1644 value1_matcher, merge_matcher)); 1645 } 1646 1647 1648 Matcher<Node*> IsPhi(const Matcher<MachineRepresentation>& type_matcher, 1649 const Matcher<Node*>& value0_matcher, 1650 const Matcher<Node*>& value1_matcher, 1651 const Matcher<Node*>& value2_matcher, 1652 const Matcher<Node*>& merge_matcher) { 1653 return MakeMatcher(new IsPhi2Matcher(type_matcher, value0_matcher, 1654 value1_matcher, value2_matcher, 1655 merge_matcher)); 1656 } 1657 1658 1659 Matcher<Node*> IsEffectPhi(const Matcher<Node*>& effect0_matcher, 1660 const Matcher<Node*>& effect1_matcher, 1661 const Matcher<Node*>& merge_matcher) { 1662 return MakeMatcher( 1663 new IsEffectPhiMatcher(effect0_matcher, effect1_matcher, merge_matcher)); 1664 } 1665 1666 1667 Matcher<Node*> IsEffectSet(const Matcher<Node*>& effect0_matcher, 1668 const Matcher<Node*>& effect1_matcher) { 1669 return MakeMatcher(new IsEffectSetMatcher(effect0_matcher, effect1_matcher)); 1670 } 1671 1672 1673 Matcher<Node*> IsProjection(const Matcher<size_t>& index_matcher, 1674 const Matcher<Node*>& base_matcher) { 1675 return MakeMatcher(new IsProjectionMatcher(index_matcher, base_matcher)); 1676 } 1677 1678 1679 Matcher<Node*> IsCall(const Matcher<const CallDescriptor*>& descriptor_matcher, 1680 const Matcher<Node*>& value0_matcher, 1681 const Matcher<Node*>& value1_matcher, 1682 const Matcher<Node*>& effect_matcher, 1683 const Matcher<Node*>& control_matcher) { 1684 std::vector<Matcher<Node*>> value_matchers; 1685 value_matchers.push_back(value0_matcher); 1686 value_matchers.push_back(value1_matcher); 1687 return MakeMatcher(new IsCallMatcher(descriptor_matcher, value_matchers, 1688 effect_matcher, control_matcher)); 1689 } 1690 1691 1692 Matcher<Node*> IsCall(const Matcher<const CallDescriptor*>& descriptor_matcher, 1693 const Matcher<Node*>& value0_matcher, 1694 const Matcher<Node*>& value1_matcher, 1695 const Matcher<Node*>& value2_matcher, 1696 const Matcher<Node*>& effect_matcher, 1697 const Matcher<Node*>& control_matcher) { 1698 std::vector<Matcher<Node*>> value_matchers; 1699 value_matchers.push_back(value0_matcher); 1700 value_matchers.push_back(value1_matcher); 1701 value_matchers.push_back(value2_matcher); 1702 return MakeMatcher(new IsCallMatcher(descriptor_matcher, value_matchers, 1703 effect_matcher, control_matcher)); 1704 } 1705 1706 1707 Matcher<Node*> IsCall(const Matcher<const CallDescriptor*>& descriptor_matcher, 1708 const Matcher<Node*>& value0_matcher, 1709 const Matcher<Node*>& value1_matcher, 1710 const Matcher<Node*>& value2_matcher, 1711 const Matcher<Node*>& value3_matcher, 1712 const Matcher<Node*>& effect_matcher, 1713 const Matcher<Node*>& control_matcher) { 1714 std::vector<Matcher<Node*>> value_matchers; 1715 value_matchers.push_back(value0_matcher); 1716 value_matchers.push_back(value1_matcher); 1717 value_matchers.push_back(value2_matcher); 1718 value_matchers.push_back(value3_matcher); 1719 return MakeMatcher(new IsCallMatcher(descriptor_matcher, value_matchers, 1720 effect_matcher, control_matcher)); 1721 } 1722 1723 1724 Matcher<Node*> IsCall(const Matcher<const CallDescriptor*>& descriptor_matcher, 1725 const Matcher<Node*>& value0_matcher, 1726 const Matcher<Node*>& value1_matcher, 1727 const Matcher<Node*>& value2_matcher, 1728 const Matcher<Node*>& value3_matcher, 1729 const Matcher<Node*>& value4_matcher, 1730 const Matcher<Node*>& effect_matcher, 1731 const Matcher<Node*>& control_matcher) { 1732 std::vector<Matcher<Node*>> value_matchers; 1733 value_matchers.push_back(value0_matcher); 1734 value_matchers.push_back(value1_matcher); 1735 value_matchers.push_back(value2_matcher); 1736 value_matchers.push_back(value3_matcher); 1737 value_matchers.push_back(value4_matcher); 1738 return MakeMatcher(new IsCallMatcher(descriptor_matcher, value_matchers, 1739 effect_matcher, control_matcher)); 1740 } 1741 1742 1743 Matcher<Node*> IsCall(const Matcher<const CallDescriptor*>& descriptor_matcher, 1744 const Matcher<Node*>& value0_matcher, 1745 const Matcher<Node*>& value1_matcher, 1746 const Matcher<Node*>& value2_matcher, 1747 const Matcher<Node*>& value3_matcher, 1748 const Matcher<Node*>& value4_matcher, 1749 const Matcher<Node*>& value5_matcher, 1750 const Matcher<Node*>& effect_matcher, 1751 const Matcher<Node*>& control_matcher) { 1752 std::vector<Matcher<Node*>> value_matchers; 1753 value_matchers.push_back(value0_matcher); 1754 value_matchers.push_back(value1_matcher); 1755 value_matchers.push_back(value2_matcher); 1756 value_matchers.push_back(value3_matcher); 1757 value_matchers.push_back(value4_matcher); 1758 value_matchers.push_back(value5_matcher); 1759 return MakeMatcher(new IsCallMatcher(descriptor_matcher, value_matchers, 1760 effect_matcher, control_matcher)); 1761 } 1762 1763 1764 Matcher<Node*> IsCall( 1765 const Matcher<const CallDescriptor*>& descriptor_matcher, 1766 const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher, 1767 const Matcher<Node*>& value2_matcher, const Matcher<Node*>& value3_matcher, 1768 const Matcher<Node*>& value4_matcher, const Matcher<Node*>& value5_matcher, 1769 const Matcher<Node*>& value6_matcher, const Matcher<Node*>& effect_matcher, 1770 const Matcher<Node*>& control_matcher) { 1771 std::vector<Matcher<Node*>> value_matchers; 1772 value_matchers.push_back(value0_matcher); 1773 value_matchers.push_back(value1_matcher); 1774 value_matchers.push_back(value2_matcher); 1775 value_matchers.push_back(value3_matcher); 1776 value_matchers.push_back(value4_matcher); 1777 value_matchers.push_back(value5_matcher); 1778 value_matchers.push_back(value6_matcher); 1779 return MakeMatcher(new IsCallMatcher(descriptor_matcher, value_matchers, 1780 effect_matcher, control_matcher)); 1781 } 1782 1783 1784 Matcher<Node*> IsTailCall( 1785 const Matcher<CallDescriptor const*>& descriptor_matcher, 1786 const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher, 1787 const Matcher<Node*>& effect_matcher, 1788 const Matcher<Node*>& control_matcher) { 1789 std::vector<Matcher<Node*>> value_matchers; 1790 value_matchers.push_back(value0_matcher); 1791 value_matchers.push_back(value1_matcher); 1792 return MakeMatcher(new IsTailCallMatcher(descriptor_matcher, value_matchers, 1793 effect_matcher, control_matcher)); 1794 } 1795 1796 1797 Matcher<Node*> IsTailCall( 1798 const Matcher<CallDescriptor const*>& descriptor_matcher, 1799 const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher, 1800 const Matcher<Node*>& value2_matcher, const Matcher<Node*>& effect_matcher, 1801 const Matcher<Node*>& control_matcher) { 1802 std::vector<Matcher<Node*>> value_matchers; 1803 value_matchers.push_back(value0_matcher); 1804 value_matchers.push_back(value1_matcher); 1805 value_matchers.push_back(value2_matcher); 1806 return MakeMatcher(new IsTailCallMatcher(descriptor_matcher, value_matchers, 1807 effect_matcher, control_matcher)); 1808 } 1809 1810 1811 Matcher<Node*> IsTailCall( 1812 const Matcher<CallDescriptor const*>& descriptor_matcher, 1813 const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher, 1814 const Matcher<Node*>& value2_matcher, const Matcher<Node*>& value3_matcher, 1815 const Matcher<Node*>& effect_matcher, 1816 const Matcher<Node*>& control_matcher) { 1817 std::vector<Matcher<Node*>> value_matchers; 1818 value_matchers.push_back(value0_matcher); 1819 value_matchers.push_back(value1_matcher); 1820 value_matchers.push_back(value2_matcher); 1821 value_matchers.push_back(value3_matcher); 1822 return MakeMatcher(new IsTailCallMatcher(descriptor_matcher, value_matchers, 1823 effect_matcher, control_matcher)); 1824 } 1825 1826 1827 Matcher<Node*> IsTailCall( 1828 const Matcher<CallDescriptor const*>& descriptor_matcher, 1829 const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher, 1830 const Matcher<Node*>& value2_matcher, const Matcher<Node*>& value3_matcher, 1831 const Matcher<Node*>& value4_matcher, const Matcher<Node*>& effect_matcher, 1832 const Matcher<Node*>& control_matcher) { 1833 std::vector<Matcher<Node*>> value_matchers; 1834 value_matchers.push_back(value0_matcher); 1835 value_matchers.push_back(value1_matcher); 1836 value_matchers.push_back(value2_matcher); 1837 value_matchers.push_back(value3_matcher); 1838 value_matchers.push_back(value4_matcher); 1839 return MakeMatcher(new IsTailCallMatcher(descriptor_matcher, value_matchers, 1840 effect_matcher, control_matcher)); 1841 } 1842 1843 1844 Matcher<Node*> IsTailCall( 1845 const Matcher<CallDescriptor const*>& descriptor_matcher, 1846 const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher, 1847 const Matcher<Node*>& value2_matcher, const Matcher<Node*>& value3_matcher, 1848 const Matcher<Node*>& value4_matcher, const Matcher<Node*>& value5_matcher, 1849 const Matcher<Node*>& effect_matcher, 1850 const Matcher<Node*>& control_matcher) { 1851 std::vector<Matcher<Node*>> value_matchers; 1852 value_matchers.push_back(value0_matcher); 1853 value_matchers.push_back(value1_matcher); 1854 value_matchers.push_back(value2_matcher); 1855 value_matchers.push_back(value3_matcher); 1856 value_matchers.push_back(value4_matcher); 1857 value_matchers.push_back(value5_matcher); 1858 return MakeMatcher(new IsTailCallMatcher(descriptor_matcher, value_matchers, 1859 effect_matcher, control_matcher)); 1860 } 1861 1862 1863 Matcher<Node*> IsTailCall( 1864 const Matcher<CallDescriptor const*>& descriptor_matcher, 1865 const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher, 1866 const Matcher<Node*>& value2_matcher, const Matcher<Node*>& value3_matcher, 1867 const Matcher<Node*>& value4_matcher, const Matcher<Node*>& value5_matcher, 1868 const Matcher<Node*>& value6_matcher, const Matcher<Node*>& effect_matcher, 1869 const Matcher<Node*>& control_matcher) { 1870 std::vector<Matcher<Node*>> value_matchers; 1871 value_matchers.push_back(value0_matcher); 1872 value_matchers.push_back(value1_matcher); 1873 value_matchers.push_back(value2_matcher); 1874 value_matchers.push_back(value3_matcher); 1875 value_matchers.push_back(value4_matcher); 1876 value_matchers.push_back(value5_matcher); 1877 value_matchers.push_back(value6_matcher); 1878 return MakeMatcher(new IsTailCallMatcher(descriptor_matcher, value_matchers, 1879 effect_matcher, control_matcher)); 1880 } 1881 1882 1883 Matcher<Node*> IsTailCall( 1884 const Matcher<CallDescriptor const*>& descriptor_matcher, 1885 const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher, 1886 const Matcher<Node*>& value2_matcher, const Matcher<Node*>& value3_matcher, 1887 const Matcher<Node*>& value4_matcher, const Matcher<Node*>& value5_matcher, 1888 const Matcher<Node*>& value6_matcher, const Matcher<Node*>& value7_matcher, 1889 const Matcher<Node*>& effect_matcher, 1890 const Matcher<Node*>& control_matcher) { 1891 std::vector<Matcher<Node*>> value_matchers; 1892 value_matchers.push_back(value0_matcher); 1893 value_matchers.push_back(value1_matcher); 1894 value_matchers.push_back(value2_matcher); 1895 value_matchers.push_back(value3_matcher); 1896 value_matchers.push_back(value4_matcher); 1897 value_matchers.push_back(value5_matcher); 1898 value_matchers.push_back(value6_matcher); 1899 value_matchers.push_back(value7_matcher); 1900 return MakeMatcher(new IsTailCallMatcher(descriptor_matcher, value_matchers, 1901 effect_matcher, control_matcher)); 1902 } 1903 1904 1905 Matcher<Node*> IsReferenceEqual(const Matcher<Type*>& type_matcher, 1906 const Matcher<Node*>& lhs_matcher, 1907 const Matcher<Node*>& rhs_matcher) { 1908 return MakeMatcher( 1909 new IsReferenceEqualMatcher(type_matcher, lhs_matcher, rhs_matcher)); 1910 } 1911 1912 1913 Matcher<Node*> IsAllocate(const Matcher<Node*>& size_matcher, 1914 const Matcher<Node*>& effect_matcher, 1915 const Matcher<Node*>& control_matcher) { 1916 return MakeMatcher( 1917 new IsAllocateMatcher(size_matcher, effect_matcher, control_matcher)); 1918 } 1919 1920 1921 Matcher<Node*> IsLoadField(const Matcher<FieldAccess>& access_matcher, 1922 const Matcher<Node*>& base_matcher, 1923 const Matcher<Node*>& effect_matcher, 1924 const Matcher<Node*>& control_matcher) { 1925 return MakeMatcher(new IsLoadFieldMatcher(access_matcher, base_matcher, 1926 effect_matcher, control_matcher)); 1927 } 1928 1929 1930 Matcher<Node*> IsStoreField(const Matcher<FieldAccess>& access_matcher, 1931 const Matcher<Node*>& base_matcher, 1932 const Matcher<Node*>& value_matcher, 1933 const Matcher<Node*>& effect_matcher, 1934 const Matcher<Node*>& control_matcher) { 1935 return MakeMatcher(new IsStoreFieldMatcher(access_matcher, base_matcher, 1936 value_matcher, effect_matcher, 1937 control_matcher)); 1938 } 1939 1940 1941 Matcher<Node*> IsLoadBuffer(const Matcher<BufferAccess>& access_matcher, 1942 const Matcher<Node*>& buffer_matcher, 1943 const Matcher<Node*>& offset_matcher, 1944 const Matcher<Node*>& length_matcher, 1945 const Matcher<Node*>& effect_matcher, 1946 const Matcher<Node*>& control_matcher) { 1947 return MakeMatcher(new IsLoadBufferMatcher(access_matcher, buffer_matcher, 1948 offset_matcher, length_matcher, 1949 effect_matcher, control_matcher)); 1950 } 1951 1952 1953 Matcher<Node*> IsStoreBuffer(const Matcher<BufferAccess>& access_matcher, 1954 const Matcher<Node*>& buffer_matcher, 1955 const Matcher<Node*>& offset_matcher, 1956 const Matcher<Node*>& length_matcher, 1957 const Matcher<Node*>& value_matcher, 1958 const Matcher<Node*>& effect_matcher, 1959 const Matcher<Node*>& control_matcher) { 1960 return MakeMatcher(new IsStoreBufferMatcher( 1961 access_matcher, buffer_matcher, offset_matcher, length_matcher, 1962 value_matcher, effect_matcher, control_matcher)); 1963 } 1964 1965 1966 Matcher<Node*> IsLoadElement(const Matcher<ElementAccess>& access_matcher, 1967 const Matcher<Node*>& base_matcher, 1968 const Matcher<Node*>& index_matcher, 1969 const Matcher<Node*>& effect_matcher, 1970 const Matcher<Node*>& control_matcher) { 1971 return MakeMatcher(new IsLoadElementMatcher(access_matcher, base_matcher, 1972 index_matcher, effect_matcher, 1973 control_matcher)); 1974 } 1975 1976 1977 Matcher<Node*> IsStoreElement(const Matcher<ElementAccess>& access_matcher, 1978 const Matcher<Node*>& base_matcher, 1979 const Matcher<Node*>& index_matcher, 1980 const Matcher<Node*>& value_matcher, 1981 const Matcher<Node*>& effect_matcher, 1982 const Matcher<Node*>& control_matcher) { 1983 return MakeMatcher(new IsStoreElementMatcher( 1984 access_matcher, base_matcher, index_matcher, value_matcher, 1985 effect_matcher, control_matcher)); 1986 } 1987 1988 1989 Matcher<Node*> IsLoad(const Matcher<LoadRepresentation>& rep_matcher, 1990 const Matcher<Node*>& base_matcher, 1991 const Matcher<Node*>& index_matcher, 1992 const Matcher<Node*>& effect_matcher, 1993 const Matcher<Node*>& control_matcher) { 1994 return MakeMatcher(new IsLoadMatcher(rep_matcher, base_matcher, index_matcher, 1995 effect_matcher, control_matcher)); 1996 } 1997 1998 1999 Matcher<Node*> IsStore(const Matcher<StoreRepresentation>& rep_matcher, 2000 const Matcher<Node*>& base_matcher, 2001 const Matcher<Node*>& index_matcher, 2002 const Matcher<Node*>& value_matcher, 2003 const Matcher<Node*>& effect_matcher, 2004 const Matcher<Node*>& control_matcher) { 2005 return MakeMatcher(new IsStoreMatcher(rep_matcher, base_matcher, 2006 index_matcher, value_matcher, 2007 effect_matcher, control_matcher)); 2008 } 2009 2010 2011 Matcher<Node*> IsToNumber(const Matcher<Node*>& base_matcher, 2012 const Matcher<Node*>& context_matcher, 2013 const Matcher<Node*>& effect_matcher, 2014 const Matcher<Node*>& control_matcher) { 2015 return MakeMatcher(new IsToNumberMatcher(base_matcher, context_matcher, 2016 effect_matcher, control_matcher)); 2017 } 2018 2019 2020 Matcher<Node*> IsLoadContext(const Matcher<ContextAccess>& access_matcher, 2021 const Matcher<Node*>& context_matcher) { 2022 return MakeMatcher(new IsLoadContextMatcher(access_matcher, context_matcher)); 2023 } 2024 2025 2026 Matcher<Node*> IsParameter(const Matcher<int> index_matcher) { 2027 return MakeMatcher(new IsParameterMatcher(index_matcher)); 2028 } 2029 2030 2031 Matcher<Node*> IsLoadFramePointer() { 2032 return MakeMatcher(new NodeMatcher(IrOpcode::kLoadFramePointer)); 2033 } 2034 2035 2036 #define IS_BINOP_MATCHER(Name) \ 2037 Matcher<Node*> Is##Name(const Matcher<Node*>& lhs_matcher, \ 2038 const Matcher<Node*>& rhs_matcher) { \ 2039 return MakeMatcher( \ 2040 new IsBinopMatcher(IrOpcode::k##Name, lhs_matcher, rhs_matcher)); \ 2041 } 2042 IS_BINOP_MATCHER(NumberEqual) 2043 IS_BINOP_MATCHER(NumberLessThan) 2044 IS_BINOP_MATCHER(NumberSubtract) 2045 IS_BINOP_MATCHER(NumberMultiply) 2046 IS_BINOP_MATCHER(NumberShiftLeft) 2047 IS_BINOP_MATCHER(NumberShiftRight) 2048 IS_BINOP_MATCHER(NumberShiftRightLogical) 2049 IS_BINOP_MATCHER(Word32And) 2050 IS_BINOP_MATCHER(Word32Or) 2051 IS_BINOP_MATCHER(Word32Sar) 2052 IS_BINOP_MATCHER(Word32Shl) 2053 IS_BINOP_MATCHER(Word32Shr) 2054 IS_BINOP_MATCHER(Word32Ror) 2055 IS_BINOP_MATCHER(Word32Equal) 2056 IS_BINOP_MATCHER(Word64And) 2057 IS_BINOP_MATCHER(Word64Or) 2058 IS_BINOP_MATCHER(Word64Sar) 2059 IS_BINOP_MATCHER(Word64Shl) 2060 IS_BINOP_MATCHER(Word64Equal) 2061 IS_BINOP_MATCHER(Int32AddWithOverflow) 2062 IS_BINOP_MATCHER(Int32Add) 2063 IS_BINOP_MATCHER(Int32Sub) 2064 IS_BINOP_MATCHER(Int32Mul) 2065 IS_BINOP_MATCHER(Int32MulHigh) 2066 IS_BINOP_MATCHER(Int32LessThan) 2067 IS_BINOP_MATCHER(Uint32LessThan) 2068 IS_BINOP_MATCHER(Uint32LessThanOrEqual) 2069 IS_BINOP_MATCHER(Int64Add) 2070 IS_BINOP_MATCHER(Int64Sub) 2071 IS_BINOP_MATCHER(JSAdd) 2072 IS_BINOP_MATCHER(Float32Max) 2073 IS_BINOP_MATCHER(Float32Min) 2074 IS_BINOP_MATCHER(Float32Equal) 2075 IS_BINOP_MATCHER(Float32LessThan) 2076 IS_BINOP_MATCHER(Float32LessThanOrEqual) 2077 IS_BINOP_MATCHER(Float64Max) 2078 IS_BINOP_MATCHER(Float64Min) 2079 IS_BINOP_MATCHER(Float64Sub) 2080 IS_BINOP_MATCHER(Float64InsertLowWord32) 2081 IS_BINOP_MATCHER(Float64InsertHighWord32) 2082 #undef IS_BINOP_MATCHER 2083 2084 2085 #define IS_UNOP_MATCHER(Name) \ 2086 Matcher<Node*> Is##Name(const Matcher<Node*>& input_matcher) { \ 2087 return MakeMatcher(new IsUnopMatcher(IrOpcode::k##Name, input_matcher)); \ 2088 } 2089 IS_UNOP_MATCHER(BooleanNot) 2090 IS_UNOP_MATCHER(ChangeFloat64ToInt32) 2091 IS_UNOP_MATCHER(ChangeFloat64ToUint32) 2092 IS_UNOP_MATCHER(ChangeInt32ToFloat64) 2093 IS_UNOP_MATCHER(ChangeInt32ToInt64) 2094 IS_UNOP_MATCHER(ChangeUint32ToFloat64) 2095 IS_UNOP_MATCHER(ChangeUint32ToUint64) 2096 IS_UNOP_MATCHER(TruncateFloat64ToFloat32) 2097 IS_UNOP_MATCHER(TruncateFloat64ToInt32) 2098 IS_UNOP_MATCHER(TruncateInt64ToInt32) 2099 IS_UNOP_MATCHER(Float32Abs) 2100 IS_UNOP_MATCHER(Float64Abs) 2101 IS_UNOP_MATCHER(Float64Sqrt) 2102 IS_UNOP_MATCHER(Float64RoundDown) 2103 IS_UNOP_MATCHER(Float64RoundTruncate) 2104 IS_UNOP_MATCHER(Float64RoundTiesAway) 2105 IS_UNOP_MATCHER(Float64ExtractLowWord32) 2106 IS_UNOP_MATCHER(Float64ExtractHighWord32) 2107 IS_UNOP_MATCHER(NumberToInt32) 2108 IS_UNOP_MATCHER(NumberToUint32) 2109 IS_UNOP_MATCHER(ObjectIsSmi) 2110 IS_UNOP_MATCHER(Word32Clz) 2111 #undef IS_UNOP_MATCHER 2112 2113 } // namespace compiler 2114 } // namespace internal 2115 } // namespace v8 2116