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 value2_matcher_(_), 327 effect_matcher_(effect_matcher), 328 control_matcher_(control_matcher), 329 has_second_return_value_(false) {} 330 331 IsReturnMatcher(const Matcher<Node*>& value_matcher, 332 const Matcher<Node*>& value2_matcher, 333 const Matcher<Node*>& effect_matcher, 334 const Matcher<Node*>& control_matcher) 335 : NodeMatcher(IrOpcode::kReturn), 336 value_matcher_(value_matcher), 337 value2_matcher_(value2_matcher), 338 effect_matcher_(effect_matcher), 339 control_matcher_(control_matcher), 340 has_second_return_value_(true) {} 341 342 void DescribeTo(std::ostream* os) const final { 343 NodeMatcher::DescribeTo(os); 344 *os << " whose value ("; 345 value_matcher_.DescribeTo(os); 346 if (has_second_return_value_) { 347 *os << ") and second value ("; 348 value2_matcher_.DescribeTo(os); 349 } 350 *os << ") and effect ("; 351 effect_matcher_.DescribeTo(os); 352 *os << ") and control ("; 353 control_matcher_.DescribeTo(os); 354 *os << ")"; 355 } 356 357 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 358 return (NodeMatcher::MatchAndExplain(node, listener) && 359 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), 360 "value", value_matcher_, listener) && 361 (!has_second_return_value_ || 362 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), 363 "value2", value2_matcher_, listener)) && 364 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", 365 effect_matcher_, listener) && 366 PrintMatchAndExplain(NodeProperties::GetControlInput(node), 367 "control", control_matcher_, listener)); 368 } 369 370 private: 371 const Matcher<Node*> value_matcher_; 372 const Matcher<Node*> value2_matcher_; 373 const Matcher<Node*> effect_matcher_; 374 const Matcher<Node*> control_matcher_; 375 bool has_second_return_value_; 376 }; 377 378 379 class IsTerminateMatcher final : public NodeMatcher { 380 public: 381 IsTerminateMatcher(const Matcher<Node*>& effect_matcher, 382 const Matcher<Node*>& control_matcher) 383 : NodeMatcher(IrOpcode::kTerminate), 384 effect_matcher_(effect_matcher), 385 control_matcher_(control_matcher) {} 386 387 void DescribeTo(std::ostream* os) const final { 388 NodeMatcher::DescribeTo(os); 389 *os << " whose effect ("; 390 effect_matcher_.DescribeTo(os); 391 *os << ") and control ("; 392 control_matcher_.DescribeTo(os); 393 *os << ")"; 394 } 395 396 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 397 return (NodeMatcher::MatchAndExplain(node, listener) && 398 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", 399 effect_matcher_, listener) && 400 PrintMatchAndExplain(NodeProperties::GetControlInput(node), 401 "control", control_matcher_, listener)); 402 } 403 404 private: 405 const Matcher<Node*> effect_matcher_; 406 const Matcher<Node*> control_matcher_; 407 }; 408 409 410 template <typename T> 411 class IsConstantMatcher final : public NodeMatcher { 412 public: 413 IsConstantMatcher(IrOpcode::Value opcode, const Matcher<T>& value_matcher) 414 : NodeMatcher(opcode), value_matcher_(value_matcher) {} 415 416 void DescribeTo(std::ostream* os) const final { 417 NodeMatcher::DescribeTo(os); 418 *os << " whose value ("; 419 value_matcher_.DescribeTo(os); 420 *os << ")"; 421 } 422 423 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 424 return (NodeMatcher::MatchAndExplain(node, listener) && 425 PrintMatchAndExplain(OpParameter<T>(node), "value", value_matcher_, 426 listener)); 427 } 428 429 private: 430 const Matcher<T> value_matcher_; 431 }; 432 433 434 class IsSelectMatcher final : public NodeMatcher { 435 public: 436 IsSelectMatcher(const Matcher<MachineRepresentation>& type_matcher, 437 const Matcher<Node*>& value0_matcher, 438 const Matcher<Node*>& value1_matcher, 439 const Matcher<Node*>& value2_matcher) 440 : NodeMatcher(IrOpcode::kSelect), 441 type_matcher_(type_matcher), 442 value0_matcher_(value0_matcher), 443 value1_matcher_(value1_matcher), 444 value2_matcher_(value2_matcher) {} 445 446 void DescribeTo(std::ostream* os) const final { 447 NodeMatcher::DescribeTo(os); 448 *os << " whose representation ("; 449 type_matcher_.DescribeTo(os); 450 *os << "), value0 ("; 451 value0_matcher_.DescribeTo(os); 452 *os << "), value1 ("; 453 value1_matcher_.DescribeTo(os); 454 *os << ") and value2 ("; 455 value2_matcher_.DescribeTo(os); 456 *os << ")"; 457 } 458 459 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 460 return ( 461 NodeMatcher::MatchAndExplain(node, listener) && 462 PrintMatchAndExplain(SelectParametersOf(node->op()).representation(), 463 "representation", type_matcher_, listener) && 464 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "value0", 465 value0_matcher_, listener) && 466 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "value1", 467 value1_matcher_, listener) && 468 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2), "value2", 469 value2_matcher_, listener)); 470 } 471 472 private: 473 const Matcher<MachineRepresentation> type_matcher_; 474 const Matcher<Node*> value0_matcher_; 475 const Matcher<Node*> value1_matcher_; 476 const Matcher<Node*> value2_matcher_; 477 }; 478 479 480 class IsPhiMatcher final : public NodeMatcher { 481 public: 482 IsPhiMatcher(const Matcher<MachineRepresentation>& type_matcher, 483 const Matcher<Node*>& value0_matcher, 484 const Matcher<Node*>& value1_matcher, 485 const Matcher<Node*>& control_matcher) 486 : NodeMatcher(IrOpcode::kPhi), 487 type_matcher_(type_matcher), 488 value0_matcher_(value0_matcher), 489 value1_matcher_(value1_matcher), 490 control_matcher_(control_matcher) {} 491 492 void DescribeTo(std::ostream* os) const final { 493 NodeMatcher::DescribeTo(os); 494 *os << " whose representation ("; 495 type_matcher_.DescribeTo(os); 496 *os << "), value0 ("; 497 value0_matcher_.DescribeTo(os); 498 *os << "), value1 ("; 499 value1_matcher_.DescribeTo(os); 500 *os << ") and control ("; 501 control_matcher_.DescribeTo(os); 502 *os << ")"; 503 } 504 505 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 506 return (NodeMatcher::MatchAndExplain(node, listener) && 507 PrintMatchAndExplain(PhiRepresentationOf(node->op()), 508 "representation", type_matcher_, listener) && 509 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), 510 "value0", value0_matcher_, listener) && 511 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), 512 "value1", value1_matcher_, listener) && 513 PrintMatchAndExplain(NodeProperties::GetControlInput(node), 514 "control", control_matcher_, listener)); 515 } 516 517 private: 518 const Matcher<MachineRepresentation> type_matcher_; 519 const Matcher<Node*> value0_matcher_; 520 const Matcher<Node*> value1_matcher_; 521 const Matcher<Node*> control_matcher_; 522 }; 523 524 525 class IsPhi2Matcher final : public NodeMatcher { 526 public: 527 IsPhi2Matcher(const Matcher<MachineRepresentation>& type_matcher, 528 const Matcher<Node*>& value0_matcher, 529 const Matcher<Node*>& value1_matcher, 530 const Matcher<Node*>& value2_matcher, 531 const Matcher<Node*>& control_matcher) 532 : NodeMatcher(IrOpcode::kPhi), 533 type_matcher_(type_matcher), 534 value0_matcher_(value0_matcher), 535 value1_matcher_(value1_matcher), 536 value2_matcher_(value2_matcher), 537 control_matcher_(control_matcher) {} 538 539 void DescribeTo(std::ostream* os) const final { 540 NodeMatcher::DescribeTo(os); 541 *os << " whose representation ("; 542 type_matcher_.DescribeTo(os); 543 *os << "), value0 ("; 544 value0_matcher_.DescribeTo(os); 545 *os << "), value1 ("; 546 value1_matcher_.DescribeTo(os); 547 *os << "), value2 ("; 548 value2_matcher_.DescribeTo(os); 549 *os << ") and control ("; 550 control_matcher_.DescribeTo(os); 551 *os << ")"; 552 } 553 554 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 555 return (NodeMatcher::MatchAndExplain(node, listener) && 556 PrintMatchAndExplain(PhiRepresentationOf(node->op()), 557 "representation", type_matcher_, listener) && 558 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), 559 "value0", value0_matcher_, listener) && 560 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), 561 "value1", value1_matcher_, listener) && 562 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2), 563 "value2", value2_matcher_, listener) && 564 PrintMatchAndExplain(NodeProperties::GetControlInput(node), 565 "control", control_matcher_, listener)); 566 } 567 568 private: 569 const Matcher<MachineRepresentation> type_matcher_; 570 const Matcher<Node*> value0_matcher_; 571 const Matcher<Node*> value1_matcher_; 572 const Matcher<Node*> value2_matcher_; 573 const Matcher<Node*> control_matcher_; 574 }; 575 576 577 class IsEffectPhiMatcher final : public NodeMatcher { 578 public: 579 IsEffectPhiMatcher(const Matcher<Node*>& effect0_matcher, 580 const Matcher<Node*>& effect1_matcher, 581 const Matcher<Node*>& control_matcher) 582 : NodeMatcher(IrOpcode::kEffectPhi), 583 effect0_matcher_(effect0_matcher), 584 effect1_matcher_(effect1_matcher), 585 control_matcher_(control_matcher) {} 586 587 void DescribeTo(std::ostream* os) const final { 588 NodeMatcher::DescribeTo(os); 589 *os << "), effect0 ("; 590 effect0_matcher_.DescribeTo(os); 591 *os << "), effect1 ("; 592 effect1_matcher_.DescribeTo(os); 593 *os << ") and control ("; 594 control_matcher_.DescribeTo(os); 595 *os << ")"; 596 } 597 598 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 599 return (NodeMatcher::MatchAndExplain(node, listener) && 600 PrintMatchAndExplain(NodeProperties::GetEffectInput(node, 0), 601 "effect0", effect0_matcher_, listener) && 602 PrintMatchAndExplain(NodeProperties::GetEffectInput(node, 1), 603 "effect1", effect1_matcher_, listener) && 604 PrintMatchAndExplain(NodeProperties::GetControlInput(node), 605 "control", control_matcher_, listener)); 606 } 607 608 private: 609 const Matcher<Node*> effect0_matcher_; 610 const Matcher<Node*> effect1_matcher_; 611 const Matcher<Node*> control_matcher_; 612 }; 613 614 615 class IsProjectionMatcher final : public NodeMatcher { 616 public: 617 IsProjectionMatcher(const Matcher<size_t>& index_matcher, 618 const Matcher<Node*>& base_matcher) 619 : NodeMatcher(IrOpcode::kProjection), 620 index_matcher_(index_matcher), 621 base_matcher_(base_matcher) {} 622 623 void DescribeTo(std::ostream* os) const final { 624 NodeMatcher::DescribeTo(os); 625 *os << " whose index ("; 626 index_matcher_.DescribeTo(os); 627 *os << ") and base ("; 628 base_matcher_.DescribeTo(os); 629 *os << ")"; 630 } 631 632 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 633 return (NodeMatcher::MatchAndExplain(node, listener) && 634 PrintMatchAndExplain(OpParameter<size_t>(node), "index", 635 index_matcher_, listener) && 636 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base", 637 base_matcher_, listener)); 638 } 639 640 private: 641 const Matcher<size_t> index_matcher_; 642 const Matcher<Node*> base_matcher_; 643 }; 644 645 646 class IsCallMatcher final : public NodeMatcher { 647 public: 648 IsCallMatcher(const Matcher<const CallDescriptor*>& descriptor_matcher, 649 const std::vector<Matcher<Node*>>& value_matchers, 650 const Matcher<Node*>& effect_matcher, 651 const Matcher<Node*>& control_matcher) 652 : NodeMatcher(IrOpcode::kCall), 653 descriptor_matcher_(descriptor_matcher), 654 value_matchers_(value_matchers), 655 effect_matcher_(effect_matcher), 656 control_matcher_(control_matcher) {} 657 658 void DescribeTo(std::ostream* os) const final { 659 NodeMatcher::DescribeTo(os); 660 for (size_t i = 0; i < value_matchers_.size(); ++i) { 661 if (i == 0) { 662 *os << " whose value0 ("; 663 } else { 664 *os << "), value" << i << " ("; 665 } 666 value_matchers_[i].DescribeTo(os); 667 } 668 *os << "), effect ("; 669 effect_matcher_.DescribeTo(os); 670 *os << ") and control ("; 671 control_matcher_.DescribeTo(os); 672 *os << ")"; 673 } 674 675 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 676 if (!NodeMatcher::MatchAndExplain(node, listener) || 677 !PrintMatchAndExplain(OpParameter<const CallDescriptor*>(node), 678 "descriptor", descriptor_matcher_, listener)) { 679 return false; 680 } 681 for (size_t i = 0; i < value_matchers_.size(); ++i) { 682 std::ostringstream ost; 683 ost << "value" << i; 684 if (!PrintMatchAndExplain( 685 NodeProperties::GetValueInput(node, static_cast<int>(i)), 686 ost.str(), value_matchers_[i], listener)) { 687 return false; 688 } 689 } 690 Node* effect_node = nullptr; 691 Node* control_node = nullptr; 692 if (NodeProperties::FirstEffectIndex(node) < node->InputCount()) { 693 effect_node = NodeProperties::GetEffectInput(node); 694 } 695 if (NodeProperties::FirstControlIndex(node) < node->InputCount()) { 696 control_node = NodeProperties::GetControlInput(node); 697 } 698 return (PrintMatchAndExplain(effect_node, "effect", effect_matcher_, 699 listener) && 700 PrintMatchAndExplain(control_node, "control", control_matcher_, 701 listener)); 702 } 703 704 private: 705 const Matcher<const CallDescriptor*> descriptor_matcher_; 706 const std::vector<Matcher<Node*>> value_matchers_; 707 const Matcher<Node*> effect_matcher_; 708 const Matcher<Node*> control_matcher_; 709 }; 710 711 712 class IsTailCallMatcher final : public NodeMatcher { 713 public: 714 IsTailCallMatcher(const Matcher<CallDescriptor const*>& descriptor_matcher, 715 const std::vector<Matcher<Node*>>& value_matchers, 716 const Matcher<Node*>& effect_matcher, 717 const Matcher<Node*>& control_matcher) 718 : NodeMatcher(IrOpcode::kTailCall), 719 descriptor_matcher_(descriptor_matcher), 720 value_matchers_(value_matchers), 721 effect_matcher_(effect_matcher), 722 control_matcher_(control_matcher) {} 723 724 void DescribeTo(std::ostream* os) const final { 725 NodeMatcher::DescribeTo(os); 726 for (size_t i = 0; i < value_matchers_.size(); ++i) { 727 if (i == 0) { 728 *os << " whose value0 ("; 729 } else { 730 *os << "), value" << i << " ("; 731 } 732 value_matchers_[i].DescribeTo(os); 733 } 734 *os << "), effect ("; 735 effect_matcher_.DescribeTo(os); 736 *os << ") and control ("; 737 control_matcher_.DescribeTo(os); 738 *os << ")"; 739 } 740 741 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 742 if (!NodeMatcher::MatchAndExplain(node, listener) || 743 !PrintMatchAndExplain(OpParameter<CallDescriptor const*>(node), 744 "descriptor", descriptor_matcher_, listener)) { 745 return false; 746 } 747 for (size_t i = 0; i < value_matchers_.size(); ++i) { 748 std::ostringstream ost; 749 ost << "value" << i; 750 if (!PrintMatchAndExplain( 751 NodeProperties::GetValueInput(node, static_cast<int>(i)), 752 ost.str(), value_matchers_[i], listener)) { 753 return false; 754 } 755 } 756 Node* effect_node = nullptr; 757 Node* control_node = nullptr; 758 if (NodeProperties::FirstEffectIndex(node) < node->InputCount()) { 759 effect_node = NodeProperties::GetEffectInput(node); 760 } 761 if (NodeProperties::FirstControlIndex(node) < node->InputCount()) { 762 control_node = NodeProperties::GetControlInput(node); 763 } 764 return (PrintMatchAndExplain(effect_node, "effect", effect_matcher_, 765 listener) && 766 PrintMatchAndExplain(control_node, "control", control_matcher_, 767 listener)); 768 } 769 770 private: 771 const Matcher<CallDescriptor const*> descriptor_matcher_; 772 const std::vector<Matcher<Node*>> value_matchers_; 773 const Matcher<Node*> effect_matcher_; 774 const Matcher<Node*> control_matcher_; 775 }; 776 777 778 class IsReferenceEqualMatcher final : public NodeMatcher { 779 public: 780 IsReferenceEqualMatcher(const Matcher<Type*>& type_matcher, 781 const Matcher<Node*>& lhs_matcher, 782 const Matcher<Node*>& rhs_matcher) 783 : NodeMatcher(IrOpcode::kReferenceEqual), 784 type_matcher_(type_matcher), 785 lhs_matcher_(lhs_matcher), 786 rhs_matcher_(rhs_matcher) {} 787 788 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 789 return (NodeMatcher::MatchAndExplain(node, listener) && 790 // TODO(bmeurer): The type parameter is currently ignored. 791 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "lhs", 792 lhs_matcher_, listener) && 793 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "rhs", 794 rhs_matcher_, listener)); 795 } 796 797 private: 798 const Matcher<Type*> type_matcher_; 799 const Matcher<Node*> lhs_matcher_; 800 const Matcher<Node*> rhs_matcher_; 801 }; 802 803 class IsSpeculativeBinopMatcher final : public NodeMatcher { 804 public: 805 IsSpeculativeBinopMatcher( 806 IrOpcode::Value opcode, 807 const Matcher<BinaryOperationHints::Hint>& hint_matcher, 808 const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher, 809 const Matcher<Node*>& effect_matcher, 810 const Matcher<Node*>& control_matcher) 811 : NodeMatcher(opcode), 812 lhs_matcher_(lhs_matcher), 813 rhs_matcher_(rhs_matcher), 814 effect_matcher_(effect_matcher), 815 control_matcher_(control_matcher) {} 816 817 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 818 return (NodeMatcher::MatchAndExplain(node, listener) && 819 // TODO(bmeurer): The type parameter is currently ignored. 820 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "lhs", 821 lhs_matcher_, listener) && 822 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "rhs", 823 rhs_matcher_, listener) && 824 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", 825 effect_matcher_, listener) && 826 PrintMatchAndExplain(NodeProperties::GetControlInput(node), 827 "control", control_matcher_, listener)); 828 } 829 830 private: 831 const Matcher<Type*> type_matcher_; 832 const Matcher<Node*> lhs_matcher_; 833 const Matcher<Node*> rhs_matcher_; 834 const Matcher<Node*> effect_matcher_; 835 const Matcher<Node*> control_matcher_; 836 }; 837 838 class IsAllocateMatcher final : public NodeMatcher { 839 public: 840 IsAllocateMatcher(const Matcher<Node*>& size_matcher, 841 const Matcher<Node*>& effect_matcher, 842 const Matcher<Node*>& control_matcher) 843 : NodeMatcher(IrOpcode::kAllocate), 844 size_matcher_(size_matcher), 845 effect_matcher_(effect_matcher), 846 control_matcher_(control_matcher) {} 847 848 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 849 return (NodeMatcher::MatchAndExplain(node, listener) && 850 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "size", 851 size_matcher_, listener) && 852 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", 853 effect_matcher_, listener) && 854 PrintMatchAndExplain(NodeProperties::GetControlInput(node), 855 "control", control_matcher_, listener)); 856 } 857 858 private: 859 const Matcher<Node*> size_matcher_; 860 const Matcher<Node*> effect_matcher_; 861 const Matcher<Node*> control_matcher_; 862 }; 863 864 865 class IsLoadFieldMatcher final : public NodeMatcher { 866 public: 867 IsLoadFieldMatcher(const Matcher<FieldAccess>& access_matcher, 868 const Matcher<Node*>& base_matcher, 869 const Matcher<Node*>& effect_matcher, 870 const Matcher<Node*>& control_matcher) 871 : NodeMatcher(IrOpcode::kLoadField), 872 access_matcher_(access_matcher), 873 base_matcher_(base_matcher), 874 effect_matcher_(effect_matcher), 875 control_matcher_(control_matcher) {} 876 877 void DescribeTo(std::ostream* os) const final { 878 NodeMatcher::DescribeTo(os); 879 *os << " whose access ("; 880 access_matcher_.DescribeTo(os); 881 *os << "), base ("; 882 base_matcher_.DescribeTo(os); 883 *os << "), effect ("; 884 effect_matcher_.DescribeTo(os); 885 *os << ") and control ("; 886 control_matcher_.DescribeTo(os); 887 *os << ")"; 888 } 889 890 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 891 return (NodeMatcher::MatchAndExplain(node, listener) && 892 PrintMatchAndExplain(OpParameter<FieldAccess>(node), "access", 893 access_matcher_, listener) && 894 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base", 895 base_matcher_, listener) && 896 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", 897 effect_matcher_, listener) && 898 PrintMatchAndExplain(NodeProperties::GetControlInput(node), 899 "control", control_matcher_, listener)); 900 } 901 902 private: 903 const Matcher<FieldAccess> access_matcher_; 904 const Matcher<Node*> base_matcher_; 905 const Matcher<Node*> effect_matcher_; 906 const Matcher<Node*> control_matcher_; 907 }; 908 909 910 class IsStoreFieldMatcher final : public NodeMatcher { 911 public: 912 IsStoreFieldMatcher(const Matcher<FieldAccess>& access_matcher, 913 const Matcher<Node*>& base_matcher, 914 const Matcher<Node*>& value_matcher, 915 const Matcher<Node*>& effect_matcher, 916 const Matcher<Node*>& control_matcher) 917 : NodeMatcher(IrOpcode::kStoreField), 918 access_matcher_(access_matcher), 919 base_matcher_(base_matcher), 920 value_matcher_(value_matcher), 921 effect_matcher_(effect_matcher), 922 control_matcher_(control_matcher) {} 923 924 void DescribeTo(std::ostream* os) const final { 925 NodeMatcher::DescribeTo(os); 926 *os << " whose access ("; 927 access_matcher_.DescribeTo(os); 928 *os << "), base ("; 929 base_matcher_.DescribeTo(os); 930 *os << "), value ("; 931 value_matcher_.DescribeTo(os); 932 *os << "), effect ("; 933 effect_matcher_.DescribeTo(os); 934 *os << ") and control ("; 935 control_matcher_.DescribeTo(os); 936 *os << ")"; 937 } 938 939 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 940 return (NodeMatcher::MatchAndExplain(node, listener) && 941 PrintMatchAndExplain(OpParameter<FieldAccess>(node), "access", 942 access_matcher_, listener) && 943 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base", 944 base_matcher_, listener) && 945 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), 946 "value", value_matcher_, listener) && 947 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", 948 effect_matcher_, listener) && 949 PrintMatchAndExplain(NodeProperties::GetControlInput(node), 950 "control", control_matcher_, listener)); 951 } 952 953 private: 954 const Matcher<FieldAccess> access_matcher_; 955 const Matcher<Node*> base_matcher_; 956 const Matcher<Node*> value_matcher_; 957 const Matcher<Node*> effect_matcher_; 958 const Matcher<Node*> control_matcher_; 959 }; 960 961 962 class IsLoadBufferMatcher final : public NodeMatcher { 963 public: 964 IsLoadBufferMatcher(const Matcher<BufferAccess>& access_matcher, 965 const Matcher<Node*>& buffer_matcher, 966 const Matcher<Node*>& offset_matcher, 967 const Matcher<Node*>& length_matcher, 968 const Matcher<Node*>& effect_matcher, 969 const Matcher<Node*>& control_matcher) 970 : NodeMatcher(IrOpcode::kLoadBuffer), 971 access_matcher_(access_matcher), 972 buffer_matcher_(buffer_matcher), 973 offset_matcher_(offset_matcher), 974 length_matcher_(length_matcher), 975 effect_matcher_(effect_matcher), 976 control_matcher_(control_matcher) {} 977 978 void DescribeTo(std::ostream* os) const final { 979 NodeMatcher::DescribeTo(os); 980 *os << " whose access ("; 981 access_matcher_.DescribeTo(os); 982 *os << "), buffer ("; 983 buffer_matcher_.DescribeTo(os); 984 *os << "), offset ("; 985 offset_matcher_.DescribeTo(os); 986 *os << "), length ("; 987 length_matcher_.DescribeTo(os); 988 *os << "), effect ("; 989 effect_matcher_.DescribeTo(os); 990 *os << ") and control ("; 991 control_matcher_.DescribeTo(os); 992 *os << ")"; 993 } 994 995 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 996 return (NodeMatcher::MatchAndExplain(node, listener) && 997 PrintMatchAndExplain(BufferAccessOf(node->op()), "access", 998 access_matcher_, listener) && 999 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), 1000 "buffer", buffer_matcher_, listener) && 1001 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), 1002 "offset", offset_matcher_, listener) && 1003 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2), 1004 "length", length_matcher_, listener) && 1005 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", 1006 effect_matcher_, listener) && 1007 PrintMatchAndExplain(NodeProperties::GetControlInput(node), 1008 "control", control_matcher_, listener)); 1009 } 1010 1011 private: 1012 const Matcher<BufferAccess> access_matcher_; 1013 const Matcher<Node*> buffer_matcher_; 1014 const Matcher<Node*> offset_matcher_; 1015 const Matcher<Node*> length_matcher_; 1016 const Matcher<Node*> effect_matcher_; 1017 const Matcher<Node*> control_matcher_; 1018 }; 1019 1020 1021 class IsStoreBufferMatcher final : public NodeMatcher { 1022 public: 1023 IsStoreBufferMatcher(const Matcher<BufferAccess>& access_matcher, 1024 const Matcher<Node*>& buffer_matcher, 1025 const Matcher<Node*>& offset_matcher, 1026 const Matcher<Node*>& length_matcher, 1027 const Matcher<Node*>& value_matcher, 1028 const Matcher<Node*>& effect_matcher, 1029 const Matcher<Node*>& control_matcher) 1030 : NodeMatcher(IrOpcode::kStoreBuffer), 1031 access_matcher_(access_matcher), 1032 buffer_matcher_(buffer_matcher), 1033 offset_matcher_(offset_matcher), 1034 length_matcher_(length_matcher), 1035 value_matcher_(value_matcher), 1036 effect_matcher_(effect_matcher), 1037 control_matcher_(control_matcher) {} 1038 1039 void DescribeTo(std::ostream* os) const final { 1040 NodeMatcher::DescribeTo(os); 1041 *os << " whose access ("; 1042 access_matcher_.DescribeTo(os); 1043 *os << "), buffer ("; 1044 buffer_matcher_.DescribeTo(os); 1045 *os << "), offset ("; 1046 offset_matcher_.DescribeTo(os); 1047 *os << "), length ("; 1048 length_matcher_.DescribeTo(os); 1049 *os << "), value ("; 1050 value_matcher_.DescribeTo(os); 1051 *os << "), effect ("; 1052 effect_matcher_.DescribeTo(os); 1053 *os << ") and control ("; 1054 control_matcher_.DescribeTo(os); 1055 *os << ")"; 1056 } 1057 1058 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 1059 return (NodeMatcher::MatchAndExplain(node, listener) && 1060 PrintMatchAndExplain(BufferAccessOf(node->op()), "access", 1061 access_matcher_, listener) && 1062 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), 1063 "buffer", buffer_matcher_, listener) && 1064 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), 1065 "offset", offset_matcher_, listener) && 1066 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2), 1067 "length", length_matcher_, listener) && 1068 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 3), 1069 "value", value_matcher_, listener) && 1070 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", 1071 effect_matcher_, listener) && 1072 PrintMatchAndExplain(NodeProperties::GetControlInput(node), 1073 "control", control_matcher_, listener)); 1074 } 1075 1076 private: 1077 const Matcher<BufferAccess> access_matcher_; 1078 const Matcher<Node*> buffer_matcher_; 1079 const Matcher<Node*> offset_matcher_; 1080 const Matcher<Node*> length_matcher_; 1081 const Matcher<Node*> value_matcher_; 1082 const Matcher<Node*> effect_matcher_; 1083 const Matcher<Node*> control_matcher_; 1084 }; 1085 1086 1087 class IsLoadElementMatcher final : public NodeMatcher { 1088 public: 1089 IsLoadElementMatcher(const Matcher<ElementAccess>& access_matcher, 1090 const Matcher<Node*>& base_matcher, 1091 const Matcher<Node*>& index_matcher, 1092 const Matcher<Node*>& effect_matcher, 1093 const Matcher<Node*>& control_matcher) 1094 : NodeMatcher(IrOpcode::kLoadElement), 1095 access_matcher_(access_matcher), 1096 base_matcher_(base_matcher), 1097 index_matcher_(index_matcher), 1098 effect_matcher_(effect_matcher), 1099 control_matcher_(control_matcher) {} 1100 1101 void DescribeTo(std::ostream* os) const final { 1102 NodeMatcher::DescribeTo(os); 1103 *os << " whose access ("; 1104 access_matcher_.DescribeTo(os); 1105 *os << "), base ("; 1106 base_matcher_.DescribeTo(os); 1107 *os << "), index ("; 1108 index_matcher_.DescribeTo(os); 1109 *os << "), effect ("; 1110 effect_matcher_.DescribeTo(os); 1111 *os << ") and control ("; 1112 control_matcher_.DescribeTo(os); 1113 *os << ")"; 1114 } 1115 1116 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 1117 return (NodeMatcher::MatchAndExplain(node, listener) && 1118 PrintMatchAndExplain(OpParameter<ElementAccess>(node), "access", 1119 access_matcher_, listener) && 1120 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base", 1121 base_matcher_, listener) && 1122 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), 1123 "index", index_matcher_, listener) && 1124 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", 1125 effect_matcher_, listener) && 1126 PrintMatchAndExplain(NodeProperties::GetControlInput(node), 1127 "control", control_matcher_, listener)); 1128 } 1129 1130 private: 1131 const Matcher<ElementAccess> access_matcher_; 1132 const Matcher<Node*> base_matcher_; 1133 const Matcher<Node*> index_matcher_; 1134 const Matcher<Node*> effect_matcher_; 1135 const Matcher<Node*> control_matcher_; 1136 }; 1137 1138 1139 class IsStoreElementMatcher final : public NodeMatcher { 1140 public: 1141 IsStoreElementMatcher(const Matcher<ElementAccess>& access_matcher, 1142 const Matcher<Node*>& base_matcher, 1143 const Matcher<Node*>& index_matcher, 1144 const Matcher<Node*>& value_matcher, 1145 const Matcher<Node*>& effect_matcher, 1146 const Matcher<Node*>& control_matcher) 1147 : NodeMatcher(IrOpcode::kStoreElement), 1148 access_matcher_(access_matcher), 1149 base_matcher_(base_matcher), 1150 index_matcher_(index_matcher), 1151 value_matcher_(value_matcher), 1152 effect_matcher_(effect_matcher), 1153 control_matcher_(control_matcher) {} 1154 1155 void DescribeTo(std::ostream* os) const final { 1156 NodeMatcher::DescribeTo(os); 1157 *os << " whose access ("; 1158 access_matcher_.DescribeTo(os); 1159 *os << "), base ("; 1160 base_matcher_.DescribeTo(os); 1161 *os << "), index ("; 1162 index_matcher_.DescribeTo(os); 1163 *os << "), value ("; 1164 value_matcher_.DescribeTo(os); 1165 *os << "), effect ("; 1166 effect_matcher_.DescribeTo(os); 1167 *os << ") and control ("; 1168 control_matcher_.DescribeTo(os); 1169 *os << ")"; 1170 } 1171 1172 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 1173 return (NodeMatcher::MatchAndExplain(node, listener) && 1174 PrintMatchAndExplain(OpParameter<ElementAccess>(node), "access", 1175 access_matcher_, listener) && 1176 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base", 1177 base_matcher_, listener) && 1178 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), 1179 "index", index_matcher_, listener) && 1180 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2), 1181 "value", value_matcher_, listener) && 1182 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", 1183 effect_matcher_, listener) && 1184 PrintMatchAndExplain(NodeProperties::GetControlInput(node), 1185 "control", control_matcher_, listener)); 1186 } 1187 1188 private: 1189 const Matcher<ElementAccess> access_matcher_; 1190 const Matcher<Node*> base_matcher_; 1191 const Matcher<Node*> index_matcher_; 1192 const Matcher<Node*> value_matcher_; 1193 const Matcher<Node*> effect_matcher_; 1194 const Matcher<Node*> control_matcher_; 1195 }; 1196 1197 1198 class IsLoadMatcher final : public NodeMatcher { 1199 public: 1200 IsLoadMatcher(const Matcher<LoadRepresentation>& rep_matcher, 1201 const Matcher<Node*>& base_matcher, 1202 const Matcher<Node*>& index_matcher, 1203 const Matcher<Node*>& effect_matcher, 1204 const Matcher<Node*>& control_matcher) 1205 : NodeMatcher(IrOpcode::kLoad), 1206 rep_matcher_(rep_matcher), 1207 base_matcher_(base_matcher), 1208 index_matcher_(index_matcher), 1209 effect_matcher_(effect_matcher), 1210 control_matcher_(control_matcher) {} 1211 1212 void DescribeTo(std::ostream* os) const final { 1213 NodeMatcher::DescribeTo(os); 1214 *os << " whose rep ("; 1215 rep_matcher_.DescribeTo(os); 1216 *os << "), base ("; 1217 base_matcher_.DescribeTo(os); 1218 *os << "), index ("; 1219 index_matcher_.DescribeTo(os); 1220 *os << "), effect ("; 1221 effect_matcher_.DescribeTo(os); 1222 *os << ") and control ("; 1223 control_matcher_.DescribeTo(os); 1224 *os << ")"; 1225 } 1226 1227 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 1228 Node* effect_node = nullptr; 1229 Node* control_node = nullptr; 1230 if (NodeProperties::FirstEffectIndex(node) < node->InputCount()) { 1231 effect_node = NodeProperties::GetEffectInput(node); 1232 } 1233 if (NodeProperties::FirstControlIndex(node) < node->InputCount()) { 1234 control_node = NodeProperties::GetControlInput(node); 1235 } 1236 return (NodeMatcher::MatchAndExplain(node, listener) && 1237 PrintMatchAndExplain(OpParameter<LoadRepresentation>(node), "rep", 1238 rep_matcher_, listener) && 1239 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base", 1240 base_matcher_, listener) && 1241 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), 1242 "index", index_matcher_, listener) && 1243 PrintMatchAndExplain(effect_node, "effect", effect_matcher_, 1244 listener) && 1245 PrintMatchAndExplain(control_node, "control", control_matcher_, 1246 listener)); 1247 } 1248 1249 private: 1250 const Matcher<LoadRepresentation> rep_matcher_; 1251 const Matcher<Node*> base_matcher_; 1252 const Matcher<Node*> index_matcher_; 1253 const Matcher<Node*> effect_matcher_; 1254 const Matcher<Node*> control_matcher_; 1255 }; 1256 1257 1258 class IsStoreMatcher final : public NodeMatcher { 1259 public: 1260 IsStoreMatcher(const Matcher<StoreRepresentation>& rep_matcher, 1261 const Matcher<Node*>& base_matcher, 1262 const Matcher<Node*>& index_matcher, 1263 const Matcher<Node*>& value_matcher, 1264 const Matcher<Node*>& effect_matcher, 1265 const Matcher<Node*>& control_matcher) 1266 : NodeMatcher(IrOpcode::kStore), 1267 rep_matcher_(rep_matcher), 1268 base_matcher_(base_matcher), 1269 index_matcher_(index_matcher), 1270 value_matcher_(value_matcher), 1271 effect_matcher_(effect_matcher), 1272 control_matcher_(control_matcher) {} 1273 1274 void DescribeTo(std::ostream* os) const final { 1275 NodeMatcher::DescribeTo(os); 1276 *os << " whose rep ("; 1277 rep_matcher_.DescribeTo(os); 1278 *os << "), base ("; 1279 base_matcher_.DescribeTo(os); 1280 *os << "), index ("; 1281 index_matcher_.DescribeTo(os); 1282 *os << "), value ("; 1283 value_matcher_.DescribeTo(os); 1284 *os << "), effect ("; 1285 effect_matcher_.DescribeTo(os); 1286 *os << ") and control ("; 1287 control_matcher_.DescribeTo(os); 1288 *os << ")"; 1289 } 1290 1291 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 1292 Node* effect_node = nullptr; 1293 Node* control_node = nullptr; 1294 if (NodeProperties::FirstEffectIndex(node) < node->InputCount()) { 1295 effect_node = NodeProperties::GetEffectInput(node); 1296 } 1297 if (NodeProperties::FirstControlIndex(node) < node->InputCount()) { 1298 control_node = NodeProperties::GetControlInput(node); 1299 } 1300 return (NodeMatcher::MatchAndExplain(node, listener) && 1301 PrintMatchAndExplain(OpParameter<StoreRepresentation>(node), "rep", 1302 rep_matcher_, listener) && 1303 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base", 1304 base_matcher_, listener) && 1305 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), 1306 "index", index_matcher_, listener) && 1307 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2), 1308 "value", value_matcher_, listener) && 1309 PrintMatchAndExplain(effect_node, "effect", effect_matcher_, 1310 listener) && 1311 PrintMatchAndExplain(control_node, "control", control_matcher_, 1312 listener)); 1313 } 1314 1315 private: 1316 const Matcher<StoreRepresentation> rep_matcher_; 1317 const Matcher<Node*> base_matcher_; 1318 const Matcher<Node*> index_matcher_; 1319 const Matcher<Node*> value_matcher_; 1320 const Matcher<Node*> effect_matcher_; 1321 const Matcher<Node*> control_matcher_; 1322 }; 1323 1324 class IsStackSlotMatcher final : public NodeMatcher { 1325 public: 1326 explicit IsStackSlotMatcher(const Matcher<MachineRepresentation>& rep_matcher) 1327 : NodeMatcher(IrOpcode::kStackSlot), rep_matcher_(rep_matcher) {} 1328 1329 void DescribeTo(std::ostream* os) const final { 1330 NodeMatcher::DescribeTo(os); 1331 *os << " whose rep ("; 1332 rep_matcher_.DescribeTo(os); 1333 *os << ")"; 1334 } 1335 1336 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 1337 return (NodeMatcher::MatchAndExplain(node, listener) && 1338 PrintMatchAndExplain(OpParameter<MachineRepresentation>(node), 1339 "rep", rep_matcher_, listener)); 1340 } 1341 1342 private: 1343 const Matcher<MachineRepresentation> rep_matcher_; 1344 }; 1345 1346 class IsTypeGuardMatcher final : public NodeMatcher { 1347 public: 1348 IsTypeGuardMatcher(const Matcher<Type*>& type_matcher, 1349 const Matcher<Node*>& value_matcher, 1350 const Matcher<Node*>& control_matcher) 1351 : NodeMatcher(IrOpcode::kTypeGuard), 1352 type_matcher_(type_matcher), 1353 value_matcher_(value_matcher), 1354 control_matcher_(control_matcher) {} 1355 1356 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 1357 return (NodeMatcher::MatchAndExplain(node, listener) && 1358 PrintMatchAndExplain(OpParameter<Type*>(node->op()), "type", 1359 type_matcher_, listener) && 1360 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), 1361 "value", value_matcher_, listener) && 1362 PrintMatchAndExplain(NodeProperties::GetControlInput(node, 0), 1363 "control", control_matcher_, listener)); 1364 } 1365 1366 private: 1367 const Matcher<Type*> type_matcher_; 1368 const Matcher<Node*> value_matcher_; 1369 const Matcher<Node*> control_matcher_; 1370 }; 1371 1372 class IsToNumberMatcher final : public NodeMatcher { 1373 public: 1374 IsToNumberMatcher(const Matcher<Node*>& base_matcher, 1375 const Matcher<Node*>& context_matcher, 1376 const Matcher<Node*>& effect_matcher, 1377 const Matcher<Node*>& control_matcher) 1378 : NodeMatcher(IrOpcode::kJSToNumber), 1379 base_matcher_(base_matcher), 1380 context_matcher_(context_matcher), 1381 effect_matcher_(effect_matcher), 1382 control_matcher_(control_matcher) {} 1383 1384 void DescribeTo(std::ostream* os) const final { 1385 NodeMatcher::DescribeTo(os); 1386 *os << " whose base ("; 1387 base_matcher_.DescribeTo(os); 1388 *os << "), context ("; 1389 context_matcher_.DescribeTo(os); 1390 *os << "), effect ("; 1391 effect_matcher_.DescribeTo(os); 1392 *os << ") and control ("; 1393 control_matcher_.DescribeTo(os); 1394 *os << ")"; 1395 } 1396 1397 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 1398 return (NodeMatcher::MatchAndExplain(node, listener) && 1399 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base", 1400 base_matcher_, listener) && 1401 PrintMatchAndExplain(NodeProperties::GetContextInput(node), 1402 "context", context_matcher_, listener) && 1403 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", 1404 effect_matcher_, listener) && 1405 PrintMatchAndExplain(NodeProperties::GetControlInput(node), 1406 "control", control_matcher_, listener)); 1407 } 1408 1409 private: 1410 const Matcher<Node*> base_matcher_; 1411 const Matcher<Node*> context_matcher_; 1412 const Matcher<Node*> effect_matcher_; 1413 const Matcher<Node*> control_matcher_; 1414 }; 1415 1416 1417 class IsLoadContextMatcher final : public NodeMatcher { 1418 public: 1419 IsLoadContextMatcher(const Matcher<ContextAccess>& access_matcher, 1420 const Matcher<Node*>& context_matcher) 1421 : NodeMatcher(IrOpcode::kJSLoadContext), 1422 access_matcher_(access_matcher), 1423 context_matcher_(context_matcher) {} 1424 1425 void DescribeTo(std::ostream* os) const final { 1426 NodeMatcher::DescribeTo(os); 1427 *os << " whose access ("; 1428 access_matcher_.DescribeTo(os); 1429 *os << ") and context ("; 1430 context_matcher_.DescribeTo(os); 1431 *os << ")"; 1432 } 1433 1434 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 1435 return (NodeMatcher::MatchAndExplain(node, listener) && 1436 PrintMatchAndExplain(OpParameter<ContextAccess>(node), "access", 1437 access_matcher_, listener) && 1438 PrintMatchAndExplain(NodeProperties::GetContextInput(node), 1439 "context", context_matcher_, listener)); 1440 } 1441 1442 private: 1443 const Matcher<ContextAccess> access_matcher_; 1444 const Matcher<Node*> context_matcher_; 1445 }; 1446 1447 class IsQuadopMatcher final : public NodeMatcher { 1448 public: 1449 IsQuadopMatcher(IrOpcode::Value opcode, const Matcher<Node*>& a_matcher, 1450 const Matcher<Node*>& b_matcher, 1451 const Matcher<Node*>& c_matcher, 1452 const Matcher<Node*>& d_matcher) 1453 : NodeMatcher(opcode), 1454 a_matcher_(a_matcher), 1455 b_matcher_(b_matcher), 1456 c_matcher_(c_matcher), 1457 d_matcher_(d_matcher) {} 1458 1459 void DescribeTo(std::ostream* os) const final { 1460 NodeMatcher::DescribeTo(os); 1461 *os << " whose a ("; 1462 a_matcher_.DescribeTo(os); 1463 *os << ") and b ("; 1464 b_matcher_.DescribeTo(os); 1465 *os << ") and c ("; 1466 c_matcher_.DescribeTo(os); 1467 *os << ") and d ("; 1468 d_matcher_.DescribeTo(os); 1469 *os << ")"; 1470 } 1471 1472 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 1473 return (NodeMatcher::MatchAndExplain(node, listener) && 1474 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "a", 1475 a_matcher_, listener) && 1476 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "b", 1477 b_matcher_, listener) && 1478 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2), "c", 1479 c_matcher_, listener) && 1480 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 3), "d", 1481 d_matcher_, listener)); 1482 } 1483 1484 private: 1485 const Matcher<Node*> a_matcher_; 1486 const Matcher<Node*> b_matcher_; 1487 const Matcher<Node*> c_matcher_; 1488 const Matcher<Node*> d_matcher_; 1489 }; 1490 1491 class IsTernopMatcher final : public NodeMatcher { 1492 public: 1493 IsTernopMatcher(IrOpcode::Value opcode, const Matcher<Node*>& lhs_matcher, 1494 const Matcher<Node*>& mid_matcher, 1495 const Matcher<Node*>& rhs_matcher) 1496 : NodeMatcher(opcode), 1497 lhs_matcher_(lhs_matcher), 1498 mid_matcher_(mid_matcher), 1499 rhs_matcher_(rhs_matcher) {} 1500 1501 void DescribeTo(std::ostream* os) const final { 1502 NodeMatcher::DescribeTo(os); 1503 *os << " whose lhs ("; 1504 lhs_matcher_.DescribeTo(os); 1505 *os << ") and mid ("; 1506 mid_matcher_.DescribeTo(os); 1507 *os << ") and rhs ("; 1508 rhs_matcher_.DescribeTo(os); 1509 *os << ")"; 1510 } 1511 1512 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 1513 return (NodeMatcher::MatchAndExplain(node, listener) && 1514 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "lhs", 1515 lhs_matcher_, listener) && 1516 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "mid", 1517 mid_matcher_, listener) && 1518 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2), "rhs", 1519 rhs_matcher_, listener)); 1520 } 1521 1522 private: 1523 const Matcher<Node*> lhs_matcher_; 1524 const Matcher<Node*> mid_matcher_; 1525 const Matcher<Node*> rhs_matcher_; 1526 }; 1527 1528 class IsBinopMatcher final : public NodeMatcher { 1529 public: 1530 IsBinopMatcher(IrOpcode::Value opcode, const Matcher<Node*>& lhs_matcher, 1531 const Matcher<Node*>& rhs_matcher) 1532 : NodeMatcher(opcode), 1533 lhs_matcher_(lhs_matcher), 1534 rhs_matcher_(rhs_matcher) {} 1535 1536 void DescribeTo(std::ostream* os) const final { 1537 NodeMatcher::DescribeTo(os); 1538 *os << " whose lhs ("; 1539 lhs_matcher_.DescribeTo(os); 1540 *os << ") and rhs ("; 1541 rhs_matcher_.DescribeTo(os); 1542 *os << ")"; 1543 } 1544 1545 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 1546 return (NodeMatcher::MatchAndExplain(node, listener) && 1547 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "lhs", 1548 lhs_matcher_, listener) && 1549 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "rhs", 1550 rhs_matcher_, listener)); 1551 } 1552 1553 private: 1554 const Matcher<Node*> lhs_matcher_; 1555 const Matcher<Node*> rhs_matcher_; 1556 }; 1557 1558 1559 class IsUnopMatcher final : public NodeMatcher { 1560 public: 1561 IsUnopMatcher(IrOpcode::Value opcode, const Matcher<Node*>& input_matcher) 1562 : NodeMatcher(opcode), input_matcher_(input_matcher) {} 1563 1564 void DescribeTo(std::ostream* os) const final { 1565 NodeMatcher::DescribeTo(os); 1566 *os << " whose input ("; 1567 input_matcher_.DescribeTo(os); 1568 *os << ")"; 1569 } 1570 1571 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 1572 return (NodeMatcher::MatchAndExplain(node, listener) && 1573 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), 1574 "input", input_matcher_, listener)); 1575 } 1576 1577 private: 1578 const Matcher<Node*> input_matcher_; 1579 }; 1580 1581 1582 class IsParameterMatcher final : public NodeMatcher { 1583 public: 1584 explicit IsParameterMatcher(const Matcher<int>& index_matcher) 1585 : NodeMatcher(IrOpcode::kParameter), index_matcher_(index_matcher) {} 1586 1587 void DescribeTo(std::ostream* os) const override { 1588 *os << "is a Parameter node with index("; 1589 index_matcher_.DescribeTo(os); 1590 *os << ")"; 1591 } 1592 1593 bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { 1594 return (NodeMatcher::MatchAndExplain(node, listener) && 1595 PrintMatchAndExplain(ParameterIndexOf(node->op()), "index", 1596 index_matcher_, listener)); 1597 } 1598 1599 private: 1600 const Matcher<int> index_matcher_; 1601 }; 1602 1603 } // namespace 1604 1605 Matcher<Node*> IsDead() { 1606 return MakeMatcher(new NodeMatcher(IrOpcode::kDead)); 1607 } 1608 1609 Matcher<Node*> IsEnd(const Matcher<Node*>& control0_matcher) { 1610 return MakeMatcher(new IsControl1Matcher(IrOpcode::kEnd, control0_matcher)); 1611 } 1612 1613 1614 Matcher<Node*> IsEnd(const Matcher<Node*>& control0_matcher, 1615 const Matcher<Node*>& control1_matcher) { 1616 return MakeMatcher(new IsControl2Matcher(IrOpcode::kEnd, control0_matcher, 1617 control1_matcher)); 1618 } 1619 1620 1621 Matcher<Node*> IsEnd(const Matcher<Node*>& control0_matcher, 1622 const Matcher<Node*>& control1_matcher, 1623 const Matcher<Node*>& control2_matcher) { 1624 return MakeMatcher(new IsControl3Matcher(IrOpcode::kEnd, control0_matcher, 1625 control1_matcher, control2_matcher)); 1626 } 1627 1628 1629 Matcher<Node*> IsBranch(const Matcher<Node*>& value_matcher, 1630 const Matcher<Node*>& control_matcher) { 1631 return MakeMatcher(new IsBranchMatcher(value_matcher, control_matcher)); 1632 } 1633 1634 1635 Matcher<Node*> IsMerge(const Matcher<Node*>& control0_matcher, 1636 const Matcher<Node*>& control1_matcher) { 1637 return MakeMatcher(new IsControl2Matcher(IrOpcode::kMerge, control0_matcher, 1638 control1_matcher)); 1639 } 1640 1641 1642 Matcher<Node*> IsMerge(const Matcher<Node*>& control0_matcher, 1643 const Matcher<Node*>& control1_matcher, 1644 const Matcher<Node*>& control2_matcher) { 1645 return MakeMatcher(new IsControl3Matcher(IrOpcode::kMerge, control0_matcher, 1646 control1_matcher, control2_matcher)); 1647 } 1648 1649 1650 Matcher<Node*> IsLoop(const Matcher<Node*>& control0_matcher, 1651 const Matcher<Node*>& control1_matcher) { 1652 return MakeMatcher(new IsControl2Matcher(IrOpcode::kLoop, control0_matcher, 1653 control1_matcher)); 1654 } 1655 1656 1657 Matcher<Node*> IsLoop(const Matcher<Node*>& control0_matcher, 1658 const Matcher<Node*>& control1_matcher, 1659 const Matcher<Node*>& control2_matcher) { 1660 return MakeMatcher(new IsControl3Matcher(IrOpcode::kLoop, control0_matcher, 1661 control1_matcher, control2_matcher)); 1662 } 1663 1664 1665 Matcher<Node*> IsIfTrue(const Matcher<Node*>& control_matcher) { 1666 return MakeMatcher(new IsControl1Matcher(IrOpcode::kIfTrue, control_matcher)); 1667 } 1668 1669 1670 Matcher<Node*> IsIfFalse(const Matcher<Node*>& control_matcher) { 1671 return MakeMatcher( 1672 new IsControl1Matcher(IrOpcode::kIfFalse, control_matcher)); 1673 } 1674 1675 1676 Matcher<Node*> IsIfSuccess(const Matcher<Node*>& control_matcher) { 1677 return MakeMatcher( 1678 new IsControl1Matcher(IrOpcode::kIfSuccess, control_matcher)); 1679 } 1680 1681 1682 Matcher<Node*> IsSwitch(const Matcher<Node*>& value_matcher, 1683 const Matcher<Node*>& control_matcher) { 1684 return MakeMatcher(new IsSwitchMatcher(value_matcher, control_matcher)); 1685 } 1686 1687 1688 Matcher<Node*> IsIfValue(const Matcher<int32_t>& value_matcher, 1689 const Matcher<Node*>& control_matcher) { 1690 return MakeMatcher(new IsIfValueMatcher(value_matcher, control_matcher)); 1691 } 1692 1693 1694 Matcher<Node*> IsIfDefault(const Matcher<Node*>& control_matcher) { 1695 return MakeMatcher( 1696 new IsControl1Matcher(IrOpcode::kIfDefault, control_matcher)); 1697 } 1698 1699 1700 Matcher<Node*> IsBeginRegion(const Matcher<Node*>& effect_matcher) { 1701 return MakeMatcher(new IsBeginRegionMatcher(effect_matcher)); 1702 } 1703 1704 1705 Matcher<Node*> IsFinishRegion(const Matcher<Node*>& value_matcher, 1706 const Matcher<Node*>& effect_matcher) { 1707 return MakeMatcher(new IsFinishRegionMatcher(value_matcher, effect_matcher)); 1708 } 1709 1710 1711 Matcher<Node*> IsReturn(const Matcher<Node*>& value_matcher, 1712 const Matcher<Node*>& effect_matcher, 1713 const Matcher<Node*>& control_matcher) { 1714 return MakeMatcher( 1715 new IsReturnMatcher(value_matcher, effect_matcher, control_matcher)); 1716 } 1717 1718 Matcher<Node*> IsReturn2(const Matcher<Node*>& value_matcher, 1719 const Matcher<Node*>& value2_matcher, 1720 const Matcher<Node*>& effect_matcher, 1721 const Matcher<Node*>& control_matcher) { 1722 return MakeMatcher(new IsReturnMatcher(value_matcher, value2_matcher, 1723 effect_matcher, control_matcher)); 1724 } 1725 1726 Matcher<Node*> IsTerminate(const Matcher<Node*>& effect_matcher, 1727 const Matcher<Node*>& control_matcher) { 1728 return MakeMatcher(new IsTerminateMatcher(effect_matcher, control_matcher)); 1729 } 1730 1731 1732 Matcher<Node*> IsExternalConstant( 1733 const Matcher<ExternalReference>& value_matcher) { 1734 return MakeMatcher(new IsConstantMatcher<ExternalReference>( 1735 IrOpcode::kExternalConstant, value_matcher)); 1736 } 1737 1738 1739 Matcher<Node*> IsHeapConstant(Handle<HeapObject> value) { 1740 return MakeMatcher(new IsConstantMatcher<Handle<HeapObject>>( 1741 IrOpcode::kHeapConstant, value)); 1742 } 1743 1744 1745 Matcher<Node*> IsInt32Constant(const Matcher<int32_t>& value_matcher) { 1746 return MakeMatcher( 1747 new IsConstantMatcher<int32_t>(IrOpcode::kInt32Constant, value_matcher)); 1748 } 1749 1750 1751 Matcher<Node*> IsInt64Constant(const Matcher<int64_t>& value_matcher) { 1752 return MakeMatcher( 1753 new IsConstantMatcher<int64_t>(IrOpcode::kInt64Constant, value_matcher)); 1754 } 1755 1756 1757 Matcher<Node*> IsFloat32Constant(const Matcher<float>& value_matcher) { 1758 return MakeMatcher( 1759 new IsConstantMatcher<float>(IrOpcode::kFloat32Constant, value_matcher)); 1760 } 1761 1762 1763 Matcher<Node*> IsFloat64Constant(const Matcher<double>& value_matcher) { 1764 return MakeMatcher( 1765 new IsConstantMatcher<double>(IrOpcode::kFloat64Constant, value_matcher)); 1766 } 1767 1768 1769 Matcher<Node*> IsNumberConstant(const Matcher<double>& value_matcher) { 1770 return MakeMatcher( 1771 new IsConstantMatcher<double>(IrOpcode::kNumberConstant, value_matcher)); 1772 } 1773 1774 1775 Matcher<Node*> IsSelect(const Matcher<MachineRepresentation>& type_matcher, 1776 const Matcher<Node*>& value0_matcher, 1777 const Matcher<Node*>& value1_matcher, 1778 const Matcher<Node*>& value2_matcher) { 1779 return MakeMatcher(new IsSelectMatcher(type_matcher, value0_matcher, 1780 value1_matcher, value2_matcher)); 1781 } 1782 1783 1784 Matcher<Node*> IsPhi(const Matcher<MachineRepresentation>& type_matcher, 1785 const Matcher<Node*>& value0_matcher, 1786 const Matcher<Node*>& value1_matcher, 1787 const Matcher<Node*>& merge_matcher) { 1788 return MakeMatcher(new IsPhiMatcher(type_matcher, value0_matcher, 1789 value1_matcher, merge_matcher)); 1790 } 1791 1792 1793 Matcher<Node*> IsPhi(const Matcher<MachineRepresentation>& type_matcher, 1794 const Matcher<Node*>& value0_matcher, 1795 const Matcher<Node*>& value1_matcher, 1796 const Matcher<Node*>& value2_matcher, 1797 const Matcher<Node*>& merge_matcher) { 1798 return MakeMatcher(new IsPhi2Matcher(type_matcher, value0_matcher, 1799 value1_matcher, value2_matcher, 1800 merge_matcher)); 1801 } 1802 1803 1804 Matcher<Node*> IsEffectPhi(const Matcher<Node*>& effect0_matcher, 1805 const Matcher<Node*>& effect1_matcher, 1806 const Matcher<Node*>& merge_matcher) { 1807 return MakeMatcher( 1808 new IsEffectPhiMatcher(effect0_matcher, effect1_matcher, merge_matcher)); 1809 } 1810 1811 1812 Matcher<Node*> IsProjection(const Matcher<size_t>& index_matcher, 1813 const Matcher<Node*>& base_matcher) { 1814 return MakeMatcher(new IsProjectionMatcher(index_matcher, base_matcher)); 1815 } 1816 1817 Matcher<Node*> IsCall(const Matcher<const CallDescriptor*>& descriptor_matcher, 1818 const Matcher<Node*>& value0_matcher, 1819 const Matcher<Node*>& effect_matcher, 1820 const Matcher<Node*>& control_matcher) { 1821 std::vector<Matcher<Node*>> value_matchers; 1822 value_matchers.push_back(value0_matcher); 1823 return MakeMatcher(new IsCallMatcher(descriptor_matcher, value_matchers, 1824 effect_matcher, control_matcher)); 1825 } 1826 1827 Matcher<Node*> IsCall(const Matcher<const CallDescriptor*>& descriptor_matcher, 1828 const Matcher<Node*>& value0_matcher, 1829 const Matcher<Node*>& value1_matcher, 1830 const Matcher<Node*>& effect_matcher, 1831 const Matcher<Node*>& control_matcher) { 1832 std::vector<Matcher<Node*>> value_matchers; 1833 value_matchers.push_back(value0_matcher); 1834 value_matchers.push_back(value1_matcher); 1835 return MakeMatcher(new IsCallMatcher(descriptor_matcher, value_matchers, 1836 effect_matcher, control_matcher)); 1837 } 1838 1839 1840 Matcher<Node*> IsCall(const Matcher<const CallDescriptor*>& descriptor_matcher, 1841 const Matcher<Node*>& value0_matcher, 1842 const Matcher<Node*>& value1_matcher, 1843 const Matcher<Node*>& value2_matcher, 1844 const Matcher<Node*>& effect_matcher, 1845 const Matcher<Node*>& control_matcher) { 1846 std::vector<Matcher<Node*>> value_matchers; 1847 value_matchers.push_back(value0_matcher); 1848 value_matchers.push_back(value1_matcher); 1849 value_matchers.push_back(value2_matcher); 1850 return MakeMatcher(new IsCallMatcher(descriptor_matcher, value_matchers, 1851 effect_matcher, control_matcher)); 1852 } 1853 1854 1855 Matcher<Node*> IsCall(const Matcher<const CallDescriptor*>& descriptor_matcher, 1856 const Matcher<Node*>& value0_matcher, 1857 const Matcher<Node*>& value1_matcher, 1858 const Matcher<Node*>& value2_matcher, 1859 const Matcher<Node*>& value3_matcher, 1860 const Matcher<Node*>& effect_matcher, 1861 const Matcher<Node*>& control_matcher) { 1862 std::vector<Matcher<Node*>> value_matchers; 1863 value_matchers.push_back(value0_matcher); 1864 value_matchers.push_back(value1_matcher); 1865 value_matchers.push_back(value2_matcher); 1866 value_matchers.push_back(value3_matcher); 1867 return MakeMatcher(new IsCallMatcher(descriptor_matcher, value_matchers, 1868 effect_matcher, control_matcher)); 1869 } 1870 1871 1872 Matcher<Node*> IsCall(const Matcher<const CallDescriptor*>& descriptor_matcher, 1873 const Matcher<Node*>& value0_matcher, 1874 const Matcher<Node*>& value1_matcher, 1875 const Matcher<Node*>& value2_matcher, 1876 const Matcher<Node*>& value3_matcher, 1877 const Matcher<Node*>& value4_matcher, 1878 const Matcher<Node*>& effect_matcher, 1879 const Matcher<Node*>& control_matcher) { 1880 std::vector<Matcher<Node*>> value_matchers; 1881 value_matchers.push_back(value0_matcher); 1882 value_matchers.push_back(value1_matcher); 1883 value_matchers.push_back(value2_matcher); 1884 value_matchers.push_back(value3_matcher); 1885 value_matchers.push_back(value4_matcher); 1886 return MakeMatcher(new IsCallMatcher(descriptor_matcher, value_matchers, 1887 effect_matcher, control_matcher)); 1888 } 1889 1890 1891 Matcher<Node*> IsCall(const Matcher<const CallDescriptor*>& descriptor_matcher, 1892 const Matcher<Node*>& value0_matcher, 1893 const Matcher<Node*>& value1_matcher, 1894 const Matcher<Node*>& value2_matcher, 1895 const Matcher<Node*>& value3_matcher, 1896 const Matcher<Node*>& value4_matcher, 1897 const Matcher<Node*>& value5_matcher, 1898 const Matcher<Node*>& effect_matcher, 1899 const Matcher<Node*>& control_matcher) { 1900 std::vector<Matcher<Node*>> value_matchers; 1901 value_matchers.push_back(value0_matcher); 1902 value_matchers.push_back(value1_matcher); 1903 value_matchers.push_back(value2_matcher); 1904 value_matchers.push_back(value3_matcher); 1905 value_matchers.push_back(value4_matcher); 1906 value_matchers.push_back(value5_matcher); 1907 return MakeMatcher(new IsCallMatcher(descriptor_matcher, value_matchers, 1908 effect_matcher, control_matcher)); 1909 } 1910 1911 1912 Matcher<Node*> IsCall( 1913 const Matcher<const CallDescriptor*>& descriptor_matcher, 1914 const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher, 1915 const Matcher<Node*>& value2_matcher, const Matcher<Node*>& value3_matcher, 1916 const Matcher<Node*>& value4_matcher, const Matcher<Node*>& value5_matcher, 1917 const Matcher<Node*>& value6_matcher, const Matcher<Node*>& effect_matcher, 1918 const Matcher<Node*>& control_matcher) { 1919 std::vector<Matcher<Node*>> value_matchers; 1920 value_matchers.push_back(value0_matcher); 1921 value_matchers.push_back(value1_matcher); 1922 value_matchers.push_back(value2_matcher); 1923 value_matchers.push_back(value3_matcher); 1924 value_matchers.push_back(value4_matcher); 1925 value_matchers.push_back(value5_matcher); 1926 value_matchers.push_back(value6_matcher); 1927 return MakeMatcher(new IsCallMatcher(descriptor_matcher, value_matchers, 1928 effect_matcher, control_matcher)); 1929 } 1930 1931 1932 Matcher<Node*> IsTailCall( 1933 const Matcher<CallDescriptor const*>& descriptor_matcher, 1934 const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher, 1935 const Matcher<Node*>& effect_matcher, 1936 const Matcher<Node*>& control_matcher) { 1937 std::vector<Matcher<Node*>> value_matchers; 1938 value_matchers.push_back(value0_matcher); 1939 value_matchers.push_back(value1_matcher); 1940 return MakeMatcher(new IsTailCallMatcher(descriptor_matcher, value_matchers, 1941 effect_matcher, control_matcher)); 1942 } 1943 1944 1945 Matcher<Node*> IsTailCall( 1946 const Matcher<CallDescriptor const*>& descriptor_matcher, 1947 const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher, 1948 const Matcher<Node*>& value2_matcher, const Matcher<Node*>& effect_matcher, 1949 const Matcher<Node*>& control_matcher) { 1950 std::vector<Matcher<Node*>> value_matchers; 1951 value_matchers.push_back(value0_matcher); 1952 value_matchers.push_back(value1_matcher); 1953 value_matchers.push_back(value2_matcher); 1954 return MakeMatcher(new IsTailCallMatcher(descriptor_matcher, value_matchers, 1955 effect_matcher, control_matcher)); 1956 } 1957 1958 1959 Matcher<Node*> IsTailCall( 1960 const Matcher<CallDescriptor const*>& descriptor_matcher, 1961 const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher, 1962 const Matcher<Node*>& value2_matcher, const Matcher<Node*>& value3_matcher, 1963 const Matcher<Node*>& effect_matcher, 1964 const Matcher<Node*>& control_matcher) { 1965 std::vector<Matcher<Node*>> value_matchers; 1966 value_matchers.push_back(value0_matcher); 1967 value_matchers.push_back(value1_matcher); 1968 value_matchers.push_back(value2_matcher); 1969 value_matchers.push_back(value3_matcher); 1970 return MakeMatcher(new IsTailCallMatcher(descriptor_matcher, value_matchers, 1971 effect_matcher, control_matcher)); 1972 } 1973 1974 1975 Matcher<Node*> IsTailCall( 1976 const Matcher<CallDescriptor const*>& descriptor_matcher, 1977 const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher, 1978 const Matcher<Node*>& value2_matcher, const Matcher<Node*>& value3_matcher, 1979 const Matcher<Node*>& value4_matcher, const Matcher<Node*>& effect_matcher, 1980 const Matcher<Node*>& control_matcher) { 1981 std::vector<Matcher<Node*>> value_matchers; 1982 value_matchers.push_back(value0_matcher); 1983 value_matchers.push_back(value1_matcher); 1984 value_matchers.push_back(value2_matcher); 1985 value_matchers.push_back(value3_matcher); 1986 value_matchers.push_back(value4_matcher); 1987 return MakeMatcher(new IsTailCallMatcher(descriptor_matcher, value_matchers, 1988 effect_matcher, control_matcher)); 1989 } 1990 1991 1992 Matcher<Node*> IsTailCall( 1993 const Matcher<CallDescriptor const*>& descriptor_matcher, 1994 const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher, 1995 const Matcher<Node*>& value2_matcher, const Matcher<Node*>& value3_matcher, 1996 const Matcher<Node*>& value4_matcher, const Matcher<Node*>& value5_matcher, 1997 const Matcher<Node*>& effect_matcher, 1998 const Matcher<Node*>& control_matcher) { 1999 std::vector<Matcher<Node*>> value_matchers; 2000 value_matchers.push_back(value0_matcher); 2001 value_matchers.push_back(value1_matcher); 2002 value_matchers.push_back(value2_matcher); 2003 value_matchers.push_back(value3_matcher); 2004 value_matchers.push_back(value4_matcher); 2005 value_matchers.push_back(value5_matcher); 2006 return MakeMatcher(new IsTailCallMatcher(descriptor_matcher, value_matchers, 2007 effect_matcher, control_matcher)); 2008 } 2009 2010 2011 Matcher<Node*> IsTailCall( 2012 const Matcher<CallDescriptor const*>& descriptor_matcher, 2013 const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher, 2014 const Matcher<Node*>& value2_matcher, const Matcher<Node*>& value3_matcher, 2015 const Matcher<Node*>& value4_matcher, const Matcher<Node*>& value5_matcher, 2016 const Matcher<Node*>& value6_matcher, const Matcher<Node*>& effect_matcher, 2017 const Matcher<Node*>& control_matcher) { 2018 std::vector<Matcher<Node*>> value_matchers; 2019 value_matchers.push_back(value0_matcher); 2020 value_matchers.push_back(value1_matcher); 2021 value_matchers.push_back(value2_matcher); 2022 value_matchers.push_back(value3_matcher); 2023 value_matchers.push_back(value4_matcher); 2024 value_matchers.push_back(value5_matcher); 2025 value_matchers.push_back(value6_matcher); 2026 return MakeMatcher(new IsTailCallMatcher(descriptor_matcher, value_matchers, 2027 effect_matcher, control_matcher)); 2028 } 2029 2030 2031 Matcher<Node*> IsTailCall( 2032 const Matcher<CallDescriptor const*>& descriptor_matcher, 2033 const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher, 2034 const Matcher<Node*>& value2_matcher, const Matcher<Node*>& value3_matcher, 2035 const Matcher<Node*>& value4_matcher, const Matcher<Node*>& value5_matcher, 2036 const Matcher<Node*>& value6_matcher, const Matcher<Node*>& value7_matcher, 2037 const Matcher<Node*>& effect_matcher, 2038 const Matcher<Node*>& control_matcher) { 2039 std::vector<Matcher<Node*>> value_matchers; 2040 value_matchers.push_back(value0_matcher); 2041 value_matchers.push_back(value1_matcher); 2042 value_matchers.push_back(value2_matcher); 2043 value_matchers.push_back(value3_matcher); 2044 value_matchers.push_back(value4_matcher); 2045 value_matchers.push_back(value5_matcher); 2046 value_matchers.push_back(value6_matcher); 2047 value_matchers.push_back(value7_matcher); 2048 return MakeMatcher(new IsTailCallMatcher(descriptor_matcher, value_matchers, 2049 effect_matcher, control_matcher)); 2050 } 2051 2052 Matcher<Node*> IsTypeGuard(const Matcher<Type*>& type_matcher, 2053 const Matcher<Node*>& value_matcher, 2054 const Matcher<Node*>& control_matcher) { 2055 return MakeMatcher( 2056 new IsTypeGuardMatcher(type_matcher, value_matcher, control_matcher)); 2057 } 2058 2059 Matcher<Node*> IsReferenceEqual(const Matcher<Type*>& type_matcher, 2060 const Matcher<Node*>& lhs_matcher, 2061 const Matcher<Node*>& rhs_matcher) { 2062 return MakeMatcher( 2063 new IsReferenceEqualMatcher(type_matcher, lhs_matcher, rhs_matcher)); 2064 } 2065 2066 Matcher<Node*> IsSpeculativeNumberAdd( 2067 const Matcher<BinaryOperationHints::Hint>& hint_matcher, 2068 const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher, 2069 const Matcher<Node*>& effect_matcher, 2070 const Matcher<Node*>& control_matcher) { 2071 return MakeMatcher(new IsSpeculativeBinopMatcher( 2072 IrOpcode::kSpeculativeNumberAdd, hint_matcher, lhs_matcher, rhs_matcher, 2073 effect_matcher, control_matcher)); 2074 } 2075 2076 Matcher<Node*> IsSpeculativeNumberSubtract( 2077 const Matcher<BinaryOperationHints::Hint>& hint_matcher, 2078 const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher, 2079 const Matcher<Node*>& effect_matcher, 2080 const Matcher<Node*>& control_matcher) { 2081 return MakeMatcher(new IsSpeculativeBinopMatcher( 2082 IrOpcode::kSpeculativeNumberSubtract, hint_matcher, lhs_matcher, 2083 rhs_matcher, effect_matcher, control_matcher)); 2084 } 2085 2086 Matcher<Node*> IsAllocate(const Matcher<Node*>& size_matcher, 2087 const Matcher<Node*>& effect_matcher, 2088 const Matcher<Node*>& control_matcher) { 2089 return MakeMatcher( 2090 new IsAllocateMatcher(size_matcher, effect_matcher, control_matcher)); 2091 } 2092 2093 2094 Matcher<Node*> IsLoadField(const Matcher<FieldAccess>& access_matcher, 2095 const Matcher<Node*>& base_matcher, 2096 const Matcher<Node*>& effect_matcher, 2097 const Matcher<Node*>& control_matcher) { 2098 return MakeMatcher(new IsLoadFieldMatcher(access_matcher, base_matcher, 2099 effect_matcher, control_matcher)); 2100 } 2101 2102 2103 Matcher<Node*> IsStoreField(const Matcher<FieldAccess>& access_matcher, 2104 const Matcher<Node*>& base_matcher, 2105 const Matcher<Node*>& value_matcher, 2106 const Matcher<Node*>& effect_matcher, 2107 const Matcher<Node*>& control_matcher) { 2108 return MakeMatcher(new IsStoreFieldMatcher(access_matcher, base_matcher, 2109 value_matcher, effect_matcher, 2110 control_matcher)); 2111 } 2112 2113 2114 Matcher<Node*> IsLoadBuffer(const Matcher<BufferAccess>& access_matcher, 2115 const Matcher<Node*>& buffer_matcher, 2116 const Matcher<Node*>& offset_matcher, 2117 const Matcher<Node*>& length_matcher, 2118 const Matcher<Node*>& effect_matcher, 2119 const Matcher<Node*>& control_matcher) { 2120 return MakeMatcher(new IsLoadBufferMatcher(access_matcher, buffer_matcher, 2121 offset_matcher, length_matcher, 2122 effect_matcher, control_matcher)); 2123 } 2124 2125 2126 Matcher<Node*> IsStoreBuffer(const Matcher<BufferAccess>& access_matcher, 2127 const Matcher<Node*>& buffer_matcher, 2128 const Matcher<Node*>& offset_matcher, 2129 const Matcher<Node*>& length_matcher, 2130 const Matcher<Node*>& value_matcher, 2131 const Matcher<Node*>& effect_matcher, 2132 const Matcher<Node*>& control_matcher) { 2133 return MakeMatcher(new IsStoreBufferMatcher( 2134 access_matcher, buffer_matcher, offset_matcher, length_matcher, 2135 value_matcher, effect_matcher, control_matcher)); 2136 } 2137 2138 2139 Matcher<Node*> IsLoadElement(const Matcher<ElementAccess>& access_matcher, 2140 const Matcher<Node*>& base_matcher, 2141 const Matcher<Node*>& index_matcher, 2142 const Matcher<Node*>& effect_matcher, 2143 const Matcher<Node*>& control_matcher) { 2144 return MakeMatcher(new IsLoadElementMatcher(access_matcher, base_matcher, 2145 index_matcher, effect_matcher, 2146 control_matcher)); 2147 } 2148 2149 2150 Matcher<Node*> IsStoreElement(const Matcher<ElementAccess>& access_matcher, 2151 const Matcher<Node*>& base_matcher, 2152 const Matcher<Node*>& index_matcher, 2153 const Matcher<Node*>& value_matcher, 2154 const Matcher<Node*>& effect_matcher, 2155 const Matcher<Node*>& control_matcher) { 2156 return MakeMatcher(new IsStoreElementMatcher( 2157 access_matcher, base_matcher, index_matcher, value_matcher, 2158 effect_matcher, control_matcher)); 2159 } 2160 2161 2162 Matcher<Node*> IsLoad(const Matcher<LoadRepresentation>& rep_matcher, 2163 const Matcher<Node*>& base_matcher, 2164 const Matcher<Node*>& index_matcher, 2165 const Matcher<Node*>& effect_matcher, 2166 const Matcher<Node*>& control_matcher) { 2167 return MakeMatcher(new IsLoadMatcher(rep_matcher, base_matcher, index_matcher, 2168 effect_matcher, control_matcher)); 2169 } 2170 2171 2172 Matcher<Node*> IsStore(const Matcher<StoreRepresentation>& rep_matcher, 2173 const Matcher<Node*>& base_matcher, 2174 const Matcher<Node*>& index_matcher, 2175 const Matcher<Node*>& value_matcher, 2176 const Matcher<Node*>& effect_matcher, 2177 const Matcher<Node*>& control_matcher) { 2178 return MakeMatcher(new IsStoreMatcher(rep_matcher, base_matcher, 2179 index_matcher, value_matcher, 2180 effect_matcher, control_matcher)); 2181 } 2182 2183 Matcher<Node*> IsStackSlot(const Matcher<MachineRepresentation>& rep_matcher) { 2184 return MakeMatcher(new IsStackSlotMatcher(rep_matcher)); 2185 } 2186 2187 Matcher<Node*> IsToNumber(const Matcher<Node*>& base_matcher, 2188 const Matcher<Node*>& context_matcher, 2189 const Matcher<Node*>& effect_matcher, 2190 const Matcher<Node*>& control_matcher) { 2191 return MakeMatcher(new IsToNumberMatcher(base_matcher, context_matcher, 2192 effect_matcher, control_matcher)); 2193 } 2194 2195 2196 Matcher<Node*> IsLoadContext(const Matcher<ContextAccess>& access_matcher, 2197 const Matcher<Node*>& context_matcher) { 2198 return MakeMatcher(new IsLoadContextMatcher(access_matcher, context_matcher)); 2199 } 2200 2201 2202 Matcher<Node*> IsParameter(const Matcher<int> index_matcher) { 2203 return MakeMatcher(new IsParameterMatcher(index_matcher)); 2204 } 2205 2206 2207 Matcher<Node*> IsLoadFramePointer() { 2208 return MakeMatcher(new NodeMatcher(IrOpcode::kLoadFramePointer)); 2209 } 2210 2211 Matcher<Node*> IsLoadParentFramePointer() { 2212 return MakeMatcher(new NodeMatcher(IrOpcode::kLoadParentFramePointer)); 2213 } 2214 2215 #define IS_QUADOP_MATCHER(Name) \ 2216 Matcher<Node*> Is##Name( \ 2217 const Matcher<Node*>& a_matcher, const Matcher<Node*>& b_matcher, \ 2218 const Matcher<Node*>& c_matcher, const Matcher<Node*>& d_matcher) { \ 2219 return MakeMatcher(new IsQuadopMatcher(IrOpcode::k##Name, a_matcher, \ 2220 b_matcher, c_matcher, d_matcher)); \ 2221 } 2222 2223 IS_QUADOP_MATCHER(Int32PairAdd) 2224 IS_QUADOP_MATCHER(Int32PairSub) 2225 IS_QUADOP_MATCHER(Int32PairMul) 2226 2227 #define IS_TERNOP_MATCHER(Name) \ 2228 Matcher<Node*> Is##Name(const Matcher<Node*>& lhs_matcher, \ 2229 const Matcher<Node*>& mid_matcher, \ 2230 const Matcher<Node*>& rhs_matcher) { \ 2231 return MakeMatcher(new IsTernopMatcher(IrOpcode::k##Name, lhs_matcher, \ 2232 mid_matcher, rhs_matcher)); \ 2233 } 2234 2235 IS_TERNOP_MATCHER(Word32PairShl) 2236 IS_TERNOP_MATCHER(Word32PairShr) 2237 IS_TERNOP_MATCHER(Word32PairSar) 2238 2239 #define IS_BINOP_MATCHER(Name) \ 2240 Matcher<Node*> Is##Name(const Matcher<Node*>& lhs_matcher, \ 2241 const Matcher<Node*>& rhs_matcher) { \ 2242 return MakeMatcher( \ 2243 new IsBinopMatcher(IrOpcode::k##Name, lhs_matcher, rhs_matcher)); \ 2244 } 2245 IS_BINOP_MATCHER(NumberEqual) 2246 IS_BINOP_MATCHER(NumberLessThan) 2247 IS_BINOP_MATCHER(NumberSubtract) 2248 IS_BINOP_MATCHER(NumberMultiply) 2249 IS_BINOP_MATCHER(NumberShiftLeft) 2250 IS_BINOP_MATCHER(NumberShiftRight) 2251 IS_BINOP_MATCHER(NumberShiftRightLogical) 2252 IS_BINOP_MATCHER(NumberImul) 2253 IS_BINOP_MATCHER(NumberAtan2) 2254 IS_BINOP_MATCHER(Word32And) 2255 IS_BINOP_MATCHER(Word32Or) 2256 IS_BINOP_MATCHER(Word32Xor) 2257 IS_BINOP_MATCHER(Word32Sar) 2258 IS_BINOP_MATCHER(Word32Shl) 2259 IS_BINOP_MATCHER(Word32Shr) 2260 IS_BINOP_MATCHER(Word32Ror) 2261 IS_BINOP_MATCHER(Word32Equal) 2262 IS_BINOP_MATCHER(Word64And) 2263 IS_BINOP_MATCHER(Word64Or) 2264 IS_BINOP_MATCHER(Word64Sar) 2265 IS_BINOP_MATCHER(Word64Shl) 2266 IS_BINOP_MATCHER(Word64Equal) 2267 IS_BINOP_MATCHER(Int32AddWithOverflow) 2268 IS_BINOP_MATCHER(Int32Add) 2269 IS_BINOP_MATCHER(Int32Sub) 2270 IS_BINOP_MATCHER(Int32Mul) 2271 IS_BINOP_MATCHER(Int32MulHigh) 2272 IS_BINOP_MATCHER(Int32LessThan) 2273 IS_BINOP_MATCHER(Uint32LessThan) 2274 IS_BINOP_MATCHER(Uint32LessThanOrEqual) 2275 IS_BINOP_MATCHER(Int64Add) 2276 IS_BINOP_MATCHER(Int64Sub) 2277 IS_BINOP_MATCHER(JSAdd) 2278 IS_BINOP_MATCHER(Float32Max) 2279 IS_BINOP_MATCHER(Float32Min) 2280 IS_BINOP_MATCHER(Float32Equal) 2281 IS_BINOP_MATCHER(Float32LessThan) 2282 IS_BINOP_MATCHER(Float32LessThanOrEqual) 2283 IS_BINOP_MATCHER(Float64Max) 2284 IS_BINOP_MATCHER(Float64Min) 2285 IS_BINOP_MATCHER(Float64Sub) 2286 IS_BINOP_MATCHER(Float64InsertLowWord32) 2287 IS_BINOP_MATCHER(Float64InsertHighWord32) 2288 #undef IS_BINOP_MATCHER 2289 2290 2291 #define IS_UNOP_MATCHER(Name) \ 2292 Matcher<Node*> Is##Name(const Matcher<Node*>& input_matcher) { \ 2293 return MakeMatcher(new IsUnopMatcher(IrOpcode::k##Name, input_matcher)); \ 2294 } 2295 IS_UNOP_MATCHER(BooleanNot) 2296 IS_UNOP_MATCHER(TruncateFloat64ToWord32) 2297 IS_UNOP_MATCHER(ChangeFloat64ToInt32) 2298 IS_UNOP_MATCHER(ChangeFloat64ToUint32) 2299 IS_UNOP_MATCHER(ChangeInt32ToFloat64) 2300 IS_UNOP_MATCHER(ChangeInt32ToInt64) 2301 IS_UNOP_MATCHER(ChangeUint32ToFloat64) 2302 IS_UNOP_MATCHER(ChangeUint32ToUint64) 2303 IS_UNOP_MATCHER(TruncateFloat64ToFloat32) 2304 IS_UNOP_MATCHER(TruncateInt64ToInt32) 2305 IS_UNOP_MATCHER(Float32Abs) 2306 IS_UNOP_MATCHER(Float64Abs) 2307 IS_UNOP_MATCHER(Float64Sqrt) 2308 IS_UNOP_MATCHER(Float64RoundDown) 2309 IS_UNOP_MATCHER(Float64RoundTruncate) 2310 IS_UNOP_MATCHER(Float64RoundTiesAway) 2311 IS_UNOP_MATCHER(Float64ExtractLowWord32) 2312 IS_UNOP_MATCHER(Float64ExtractHighWord32) 2313 IS_UNOP_MATCHER(NumberAbs) 2314 IS_UNOP_MATCHER(NumberAtan) 2315 IS_UNOP_MATCHER(NumberAtanh) 2316 IS_UNOP_MATCHER(NumberCeil) 2317 IS_UNOP_MATCHER(NumberClz32) 2318 IS_UNOP_MATCHER(NumberCbrt) 2319 IS_UNOP_MATCHER(NumberCos) 2320 IS_UNOP_MATCHER(NumberExp) 2321 IS_UNOP_MATCHER(NumberExpm1) 2322 IS_UNOP_MATCHER(NumberFloor) 2323 IS_UNOP_MATCHER(NumberFround) 2324 IS_UNOP_MATCHER(NumberLog) 2325 IS_UNOP_MATCHER(NumberLog1p) 2326 IS_UNOP_MATCHER(NumberLog10) 2327 IS_UNOP_MATCHER(NumberLog2) 2328 IS_UNOP_MATCHER(NumberRound) 2329 IS_UNOP_MATCHER(NumberSin) 2330 IS_UNOP_MATCHER(NumberSqrt) 2331 IS_UNOP_MATCHER(NumberTan) 2332 IS_UNOP_MATCHER(NumberTrunc) 2333 IS_UNOP_MATCHER(NumberToInt32) 2334 IS_UNOP_MATCHER(NumberToUint32) 2335 IS_UNOP_MATCHER(PlainPrimitiveToNumber) 2336 IS_UNOP_MATCHER(ObjectIsReceiver) 2337 IS_UNOP_MATCHER(ObjectIsSmi) 2338 IS_UNOP_MATCHER(StringFromCharCode) 2339 IS_UNOP_MATCHER(Word32Clz) 2340 IS_UNOP_MATCHER(Word32Ctz) 2341 IS_UNOP_MATCHER(Word32Popcnt) 2342 #undef IS_UNOP_MATCHER 2343 2344 } // namespace compiler 2345 } // namespace internal 2346 } // namespace v8 2347