1 // Copyright 2014 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "src/compiler/graph-unittest.h" 6 7 #include <ostream> // NOLINT(readability/streams) 8 9 #include "src/compiler/node-properties-inl.h" 10 11 using testing::_; 12 using testing::MakeMatcher; 13 using testing::MatcherInterface; 14 using testing::MatchResultListener; 15 using testing::StringMatchResultListener; 16 17 namespace v8 { 18 namespace internal { 19 20 // TODO(bmeurer): Find a new home for these functions. 21 template <typename T> 22 inline std::ostream& operator<<(std::ostream& os, const Unique<T>& value) { 23 return os << *value.handle(); 24 } 25 inline std::ostream& operator<<(std::ostream& os, 26 const ExternalReference& value) { 27 OStringStream ost; 28 compiler::StaticParameterTraits<ExternalReference>::PrintTo(ost, value); 29 return os << ost.c_str(); 30 } 31 32 namespace compiler { 33 34 GraphTest::GraphTest(int num_parameters) : common_(zone()), graph_(zone()) { 35 graph()->SetStart(graph()->NewNode(common()->Start(num_parameters))); 36 } 37 38 39 GraphTest::~GraphTest() {} 40 41 42 Node* GraphTest::Parameter(int32_t index) { 43 return graph()->NewNode(common()->Parameter(index), graph()->start()); 44 } 45 46 47 Node* GraphTest::Float32Constant(volatile float value) { 48 return graph()->NewNode(common()->Float32Constant(value)); 49 } 50 51 52 Node* GraphTest::Float64Constant(volatile double value) { 53 return graph()->NewNode(common()->Float64Constant(value)); 54 } 55 56 57 Node* GraphTest::Int32Constant(int32_t value) { 58 return graph()->NewNode(common()->Int32Constant(value)); 59 } 60 61 62 Node* GraphTest::Int64Constant(int64_t value) { 63 return graph()->NewNode(common()->Int64Constant(value)); 64 } 65 66 67 Node* GraphTest::NumberConstant(volatile double value) { 68 return graph()->NewNode(common()->NumberConstant(value)); 69 } 70 71 72 Node* GraphTest::HeapConstant(const Unique<HeapObject>& value) { 73 return graph()->NewNode(common()->HeapConstant(value)); 74 } 75 76 77 Node* GraphTest::FalseConstant() { 78 return HeapConstant( 79 Unique<HeapObject>::CreateImmovable(factory()->false_value())); 80 } 81 82 83 Node* GraphTest::TrueConstant() { 84 return HeapConstant( 85 Unique<HeapObject>::CreateImmovable(factory()->true_value())); 86 } 87 88 89 Matcher<Node*> GraphTest::IsFalseConstant() { 90 return IsHeapConstant( 91 Unique<HeapObject>::CreateImmovable(factory()->false_value())); 92 } 93 94 95 Matcher<Node*> GraphTest::IsTrueConstant() { 96 return IsHeapConstant( 97 Unique<HeapObject>::CreateImmovable(factory()->true_value())); 98 } 99 100 namespace { 101 102 template <typename T> 103 bool PrintMatchAndExplain(const T& value, const char* value_name, 104 const Matcher<T>& value_matcher, 105 MatchResultListener* listener) { 106 StringMatchResultListener value_listener; 107 if (!value_matcher.MatchAndExplain(value, &value_listener)) { 108 *listener << "whose " << value_name << " " << value << " doesn't match"; 109 if (value_listener.str() != "") { 110 *listener << ", " << value_listener.str(); 111 } 112 return false; 113 } 114 return true; 115 } 116 117 118 class NodeMatcher : public MatcherInterface<Node*> { 119 public: 120 explicit NodeMatcher(IrOpcode::Value opcode) : opcode_(opcode) {} 121 122 virtual void DescribeTo(std::ostream* os) const OVERRIDE { 123 *os << "is a " << IrOpcode::Mnemonic(opcode_) << " node"; 124 } 125 126 virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const 127 OVERRIDE { 128 if (node == NULL) { 129 *listener << "which is NULL"; 130 return false; 131 } 132 if (node->opcode() != opcode_) { 133 *listener << "whose opcode is " << IrOpcode::Mnemonic(node->opcode()) 134 << " but should have been " << IrOpcode::Mnemonic(opcode_); 135 return false; 136 } 137 return true; 138 } 139 140 private: 141 const IrOpcode::Value opcode_; 142 }; 143 144 145 class IsBranchMatcher FINAL : public NodeMatcher { 146 public: 147 IsBranchMatcher(const Matcher<Node*>& value_matcher, 148 const Matcher<Node*>& control_matcher) 149 : NodeMatcher(IrOpcode::kBranch), 150 value_matcher_(value_matcher), 151 control_matcher_(control_matcher) {} 152 153 virtual void DescribeTo(std::ostream* os) const OVERRIDE { 154 NodeMatcher::DescribeTo(os); 155 *os << " whose value ("; 156 value_matcher_.DescribeTo(os); 157 *os << ") and control ("; 158 control_matcher_.DescribeTo(os); 159 *os << ")"; 160 } 161 162 virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const 163 OVERRIDE { 164 return (NodeMatcher::MatchAndExplain(node, listener) && 165 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), 166 "value", value_matcher_, listener) && 167 PrintMatchAndExplain(NodeProperties::GetControlInput(node), 168 "control", control_matcher_, listener)); 169 } 170 171 private: 172 const Matcher<Node*> value_matcher_; 173 const Matcher<Node*> control_matcher_; 174 }; 175 176 177 class IsMergeMatcher FINAL : public NodeMatcher { 178 public: 179 IsMergeMatcher(const Matcher<Node*>& control0_matcher, 180 const Matcher<Node*>& control1_matcher) 181 : NodeMatcher(IrOpcode::kMerge), 182 control0_matcher_(control0_matcher), 183 control1_matcher_(control1_matcher) {} 184 185 virtual void DescribeTo(std::ostream* os) const OVERRIDE { 186 NodeMatcher::DescribeTo(os); 187 *os << " whose control0 ("; 188 control0_matcher_.DescribeTo(os); 189 *os << ") and control1 ("; 190 control1_matcher_.DescribeTo(os); 191 *os << ")"; 192 } 193 194 virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const 195 OVERRIDE { 196 return (NodeMatcher::MatchAndExplain(node, listener) && 197 PrintMatchAndExplain(NodeProperties::GetControlInput(node, 0), 198 "control0", control0_matcher_, listener) && 199 PrintMatchAndExplain(NodeProperties::GetControlInput(node, 1), 200 "control1", control1_matcher_, listener)); 201 } 202 203 private: 204 const Matcher<Node*> control0_matcher_; 205 const Matcher<Node*> control1_matcher_; 206 }; 207 208 209 class IsControl1Matcher FINAL : public NodeMatcher { 210 public: 211 IsControl1Matcher(IrOpcode::Value opcode, 212 const Matcher<Node*>& control_matcher) 213 : NodeMatcher(opcode), control_matcher_(control_matcher) {} 214 215 virtual void DescribeTo(std::ostream* os) const OVERRIDE { 216 NodeMatcher::DescribeTo(os); 217 *os << " whose control ("; 218 control_matcher_.DescribeTo(os); 219 *os << ")"; 220 } 221 222 virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const 223 OVERRIDE { 224 return (NodeMatcher::MatchAndExplain(node, listener) && 225 PrintMatchAndExplain(NodeProperties::GetControlInput(node), 226 "control", control_matcher_, listener)); 227 } 228 229 private: 230 const Matcher<Node*> control_matcher_; 231 }; 232 233 234 class IsFinishMatcher FINAL : public NodeMatcher { 235 public: 236 IsFinishMatcher(const Matcher<Node*>& value_matcher, 237 const Matcher<Node*>& effect_matcher) 238 : NodeMatcher(IrOpcode::kFinish), 239 value_matcher_(value_matcher), 240 effect_matcher_(effect_matcher) {} 241 242 virtual void DescribeTo(std::ostream* os) const OVERRIDE { 243 NodeMatcher::DescribeTo(os); 244 *os << " whose value ("; 245 value_matcher_.DescribeTo(os); 246 *os << ") and effect ("; 247 effect_matcher_.DescribeTo(os); 248 *os << ")"; 249 } 250 251 virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const 252 OVERRIDE { 253 return (NodeMatcher::MatchAndExplain(node, listener) && 254 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), 255 "value", value_matcher_, listener) && 256 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", 257 effect_matcher_, listener)); 258 } 259 260 private: 261 const Matcher<Node*> value_matcher_; 262 const Matcher<Node*> effect_matcher_; 263 }; 264 265 266 template <typename T> 267 class IsConstantMatcher FINAL : public NodeMatcher { 268 public: 269 IsConstantMatcher(IrOpcode::Value opcode, const Matcher<T>& value_matcher) 270 : NodeMatcher(opcode), value_matcher_(value_matcher) {} 271 272 virtual void DescribeTo(std::ostream* os) const OVERRIDE { 273 NodeMatcher::DescribeTo(os); 274 *os << " whose value ("; 275 value_matcher_.DescribeTo(os); 276 *os << ")"; 277 } 278 279 virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const 280 OVERRIDE { 281 return (NodeMatcher::MatchAndExplain(node, listener) && 282 PrintMatchAndExplain(OpParameter<T>(node), "value", value_matcher_, 283 listener)); 284 } 285 286 private: 287 const Matcher<T> value_matcher_; 288 }; 289 290 291 class IsPhiMatcher FINAL : public NodeMatcher { 292 public: 293 IsPhiMatcher(const Matcher<MachineType>& type_matcher, 294 const Matcher<Node*>& value0_matcher, 295 const Matcher<Node*>& value1_matcher, 296 const Matcher<Node*>& control_matcher) 297 : NodeMatcher(IrOpcode::kPhi), 298 type_matcher_(type_matcher), 299 value0_matcher_(value0_matcher), 300 value1_matcher_(value1_matcher), 301 control_matcher_(control_matcher) {} 302 303 virtual void DescribeTo(std::ostream* os) const OVERRIDE { 304 NodeMatcher::DescribeTo(os); 305 *os << " whose type ("; 306 type_matcher_.DescribeTo(os); 307 *os << "), value0 ("; 308 value0_matcher_.DescribeTo(os); 309 *os << "), value1 ("; 310 value1_matcher_.DescribeTo(os); 311 *os << ") and control ("; 312 control_matcher_.DescribeTo(os); 313 *os << ")"; 314 } 315 316 virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const 317 OVERRIDE { 318 return (NodeMatcher::MatchAndExplain(node, listener) && 319 PrintMatchAndExplain(OpParameter<MachineType>(node), "type", 320 type_matcher_, listener) && 321 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), 322 "value0", value0_matcher_, listener) && 323 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), 324 "value1", value1_matcher_, listener) && 325 PrintMatchAndExplain(NodeProperties::GetControlInput(node), 326 "control", control_matcher_, listener)); 327 } 328 329 private: 330 const Matcher<MachineType> type_matcher_; 331 const Matcher<Node*> value0_matcher_; 332 const Matcher<Node*> value1_matcher_; 333 const Matcher<Node*> control_matcher_; 334 }; 335 336 337 class IsProjectionMatcher FINAL : public NodeMatcher { 338 public: 339 IsProjectionMatcher(const Matcher<size_t>& index_matcher, 340 const Matcher<Node*>& base_matcher) 341 : NodeMatcher(IrOpcode::kProjection), 342 index_matcher_(index_matcher), 343 base_matcher_(base_matcher) {} 344 345 virtual void DescribeTo(std::ostream* os) const OVERRIDE { 346 NodeMatcher::DescribeTo(os); 347 *os << " whose index ("; 348 index_matcher_.DescribeTo(os); 349 *os << ") and base ("; 350 base_matcher_.DescribeTo(os); 351 *os << ")"; 352 } 353 354 virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const 355 OVERRIDE { 356 return (NodeMatcher::MatchAndExplain(node, listener) && 357 PrintMatchAndExplain(OpParameter<size_t>(node), "index", 358 index_matcher_, listener) && 359 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base", 360 base_matcher_, listener)); 361 } 362 363 private: 364 const Matcher<size_t> index_matcher_; 365 const Matcher<Node*> base_matcher_; 366 }; 367 368 369 class IsCallMatcher FINAL : public NodeMatcher { 370 public: 371 IsCallMatcher(const Matcher<CallDescriptor*>& descriptor_matcher, 372 const Matcher<Node*>& value0_matcher, 373 const Matcher<Node*>& value1_matcher, 374 const Matcher<Node*>& value2_matcher, 375 const Matcher<Node*>& value3_matcher, 376 const Matcher<Node*>& effect_matcher, 377 const Matcher<Node*>& control_matcher) 378 : NodeMatcher(IrOpcode::kCall), 379 descriptor_matcher_(descriptor_matcher), 380 value0_matcher_(value0_matcher), 381 value1_matcher_(value1_matcher), 382 value2_matcher_(value2_matcher), 383 value3_matcher_(value3_matcher), 384 effect_matcher_(effect_matcher), 385 control_matcher_(control_matcher) {} 386 387 virtual void DescribeTo(std::ostream* os) const OVERRIDE { 388 NodeMatcher::DescribeTo(os); 389 *os << " whose value0 ("; 390 value0_matcher_.DescribeTo(os); 391 *os << ") and value1 ("; 392 value1_matcher_.DescribeTo(os); 393 *os << ") and value2 ("; 394 value2_matcher_.DescribeTo(os); 395 *os << ") and value3 ("; 396 value3_matcher_.DescribeTo(os); 397 *os << ") and effect ("; 398 effect_matcher_.DescribeTo(os); 399 *os << ") and control ("; 400 control_matcher_.DescribeTo(os); 401 *os << ")"; 402 } 403 404 virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const 405 OVERRIDE { 406 return (NodeMatcher::MatchAndExplain(node, listener) && 407 PrintMatchAndExplain(OpParameter<CallDescriptor*>(node), 408 "descriptor", descriptor_matcher_, listener) && 409 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), 410 "value0", value0_matcher_, listener) && 411 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), 412 "value1", value1_matcher_, listener) && 413 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2), 414 "value2", value2_matcher_, listener) && 415 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 3), 416 "value3", value3_matcher_, listener) && 417 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", 418 effect_matcher_, listener) && 419 PrintMatchAndExplain(NodeProperties::GetControlInput(node), 420 "control", control_matcher_, listener)); 421 } 422 423 private: 424 const Matcher<CallDescriptor*> descriptor_matcher_; 425 const Matcher<Node*> value0_matcher_; 426 const Matcher<Node*> value1_matcher_; 427 const Matcher<Node*> value2_matcher_; 428 const Matcher<Node*> value3_matcher_; 429 const Matcher<Node*> effect_matcher_; 430 const Matcher<Node*> control_matcher_; 431 }; 432 433 434 class IsLoadMatcher FINAL : public NodeMatcher { 435 public: 436 IsLoadMatcher(const Matcher<LoadRepresentation>& rep_matcher, 437 const Matcher<Node*>& base_matcher, 438 const Matcher<Node*>& index_matcher, 439 const Matcher<Node*>& effect_matcher) 440 : NodeMatcher(IrOpcode::kLoad), 441 rep_matcher_(rep_matcher), 442 base_matcher_(base_matcher), 443 index_matcher_(index_matcher), 444 effect_matcher_(effect_matcher) {} 445 446 virtual void DescribeTo(std::ostream* os) const OVERRIDE { 447 NodeMatcher::DescribeTo(os); 448 *os << " whose rep ("; 449 rep_matcher_.DescribeTo(os); 450 *os << "), base ("; 451 base_matcher_.DescribeTo(os); 452 *os << "), index ("; 453 index_matcher_.DescribeTo(os); 454 *os << ") and effect ("; 455 effect_matcher_.DescribeTo(os); 456 *os << ")"; 457 } 458 459 virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const 460 OVERRIDE { 461 return (NodeMatcher::MatchAndExplain(node, listener) && 462 PrintMatchAndExplain(OpParameter<LoadRepresentation>(node), "rep", 463 rep_matcher_, listener) && 464 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base", 465 base_matcher_, listener) && 466 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), 467 "index", index_matcher_, listener) && 468 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", 469 effect_matcher_, listener)); 470 } 471 472 private: 473 const Matcher<LoadRepresentation> rep_matcher_; 474 const Matcher<Node*> base_matcher_; 475 const Matcher<Node*> index_matcher_; 476 const Matcher<Node*> effect_matcher_; 477 }; 478 479 480 class IsStoreMatcher FINAL : public NodeMatcher { 481 public: 482 IsStoreMatcher(const Matcher<MachineType>& type_matcher, 483 const Matcher<WriteBarrierKind> write_barrier_matcher, 484 const Matcher<Node*>& base_matcher, 485 const Matcher<Node*>& index_matcher, 486 const Matcher<Node*>& value_matcher, 487 const Matcher<Node*>& effect_matcher, 488 const Matcher<Node*>& control_matcher) 489 : NodeMatcher(IrOpcode::kStore), 490 type_matcher_(type_matcher), 491 write_barrier_matcher_(write_barrier_matcher), 492 base_matcher_(base_matcher), 493 index_matcher_(index_matcher), 494 value_matcher_(value_matcher), 495 effect_matcher_(effect_matcher), 496 control_matcher_(control_matcher) {} 497 498 virtual void DescribeTo(std::ostream* os) const OVERRIDE { 499 NodeMatcher::DescribeTo(os); 500 *os << " whose type ("; 501 type_matcher_.DescribeTo(os); 502 *os << "), write barrier ("; 503 write_barrier_matcher_.DescribeTo(os); 504 *os << "), base ("; 505 base_matcher_.DescribeTo(os); 506 *os << "), index ("; 507 index_matcher_.DescribeTo(os); 508 *os << "), value ("; 509 value_matcher_.DescribeTo(os); 510 *os << "), effect ("; 511 effect_matcher_.DescribeTo(os); 512 *os << ") and control ("; 513 control_matcher_.DescribeTo(os); 514 *os << ")"; 515 } 516 517 virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const 518 OVERRIDE { 519 return (NodeMatcher::MatchAndExplain(node, listener) && 520 PrintMatchAndExplain( 521 OpParameter<StoreRepresentation>(node).machine_type(), "type", 522 type_matcher_, listener) && 523 PrintMatchAndExplain( 524 OpParameter<StoreRepresentation>(node).write_barrier_kind(), 525 "write barrier", write_barrier_matcher_, listener) && 526 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base", 527 base_matcher_, listener) && 528 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), 529 "index", index_matcher_, listener) && 530 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2), 531 "value", value_matcher_, listener) && 532 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", 533 effect_matcher_, listener) && 534 PrintMatchAndExplain(NodeProperties::GetControlInput(node), 535 "control", control_matcher_, listener)); 536 } 537 538 private: 539 const Matcher<MachineType> type_matcher_; 540 const Matcher<WriteBarrierKind> write_barrier_matcher_; 541 const Matcher<Node*> base_matcher_; 542 const Matcher<Node*> index_matcher_; 543 const Matcher<Node*> value_matcher_; 544 const Matcher<Node*> effect_matcher_; 545 const Matcher<Node*> control_matcher_; 546 }; 547 548 549 class IsBinopMatcher FINAL : public NodeMatcher { 550 public: 551 IsBinopMatcher(IrOpcode::Value opcode, const Matcher<Node*>& lhs_matcher, 552 const Matcher<Node*>& rhs_matcher) 553 : NodeMatcher(opcode), 554 lhs_matcher_(lhs_matcher), 555 rhs_matcher_(rhs_matcher) {} 556 557 virtual void DescribeTo(std::ostream* os) const OVERRIDE { 558 NodeMatcher::DescribeTo(os); 559 *os << " whose lhs ("; 560 lhs_matcher_.DescribeTo(os); 561 *os << ") and rhs ("; 562 rhs_matcher_.DescribeTo(os); 563 *os << ")"; 564 } 565 566 virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const 567 OVERRIDE { 568 return (NodeMatcher::MatchAndExplain(node, listener) && 569 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "lhs", 570 lhs_matcher_, listener) && 571 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "rhs", 572 rhs_matcher_, listener)); 573 } 574 575 private: 576 const Matcher<Node*> lhs_matcher_; 577 const Matcher<Node*> rhs_matcher_; 578 }; 579 580 581 class IsUnopMatcher FINAL : public NodeMatcher { 582 public: 583 IsUnopMatcher(IrOpcode::Value opcode, const Matcher<Node*>& input_matcher) 584 : NodeMatcher(opcode), input_matcher_(input_matcher) {} 585 586 virtual void DescribeTo(std::ostream* os) const OVERRIDE { 587 NodeMatcher::DescribeTo(os); 588 *os << " whose input ("; 589 input_matcher_.DescribeTo(os); 590 *os << ")"; 591 } 592 593 virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const 594 OVERRIDE { 595 return (NodeMatcher::MatchAndExplain(node, listener) && 596 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), 597 "input", input_matcher_, listener)); 598 } 599 600 private: 601 const Matcher<Node*> input_matcher_; 602 }; 603 } 604 605 606 Matcher<Node*> IsBranch(const Matcher<Node*>& value_matcher, 607 const Matcher<Node*>& control_matcher) { 608 return MakeMatcher(new IsBranchMatcher(value_matcher, control_matcher)); 609 } 610 611 612 Matcher<Node*> IsMerge(const Matcher<Node*>& control0_matcher, 613 const Matcher<Node*>& control1_matcher) { 614 return MakeMatcher(new IsMergeMatcher(control0_matcher, control1_matcher)); 615 } 616 617 618 Matcher<Node*> IsIfTrue(const Matcher<Node*>& control_matcher) { 619 return MakeMatcher(new IsControl1Matcher(IrOpcode::kIfTrue, control_matcher)); 620 } 621 622 623 Matcher<Node*> IsIfFalse(const Matcher<Node*>& control_matcher) { 624 return MakeMatcher( 625 new IsControl1Matcher(IrOpcode::kIfFalse, control_matcher)); 626 } 627 628 629 Matcher<Node*> IsControlEffect(const Matcher<Node*>& control_matcher) { 630 return MakeMatcher( 631 new IsControl1Matcher(IrOpcode::kControlEffect, control_matcher)); 632 } 633 634 635 Matcher<Node*> IsValueEffect(const Matcher<Node*>& value_matcher) { 636 return MakeMatcher(new IsUnopMatcher(IrOpcode::kValueEffect, value_matcher)); 637 } 638 639 640 Matcher<Node*> IsFinish(const Matcher<Node*>& value_matcher, 641 const Matcher<Node*>& effect_matcher) { 642 return MakeMatcher(new IsFinishMatcher(value_matcher, effect_matcher)); 643 } 644 645 646 Matcher<Node*> IsExternalConstant( 647 const Matcher<ExternalReference>& value_matcher) { 648 return MakeMatcher(new IsConstantMatcher<ExternalReference>( 649 IrOpcode::kExternalConstant, value_matcher)); 650 } 651 652 653 Matcher<Node*> IsHeapConstant( 654 const Matcher<Unique<HeapObject> >& value_matcher) { 655 return MakeMatcher(new IsConstantMatcher<Unique<HeapObject> >( 656 IrOpcode::kHeapConstant, value_matcher)); 657 } 658 659 660 Matcher<Node*> IsInt32Constant(const Matcher<int32_t>& value_matcher) { 661 return MakeMatcher( 662 new IsConstantMatcher<int32_t>(IrOpcode::kInt32Constant, value_matcher)); 663 } 664 665 666 Matcher<Node*> IsInt64Constant(const Matcher<int64_t>& value_matcher) { 667 return MakeMatcher( 668 new IsConstantMatcher<int64_t>(IrOpcode::kInt64Constant, value_matcher)); 669 } 670 671 672 Matcher<Node*> IsFloat32Constant(const Matcher<float>& value_matcher) { 673 return MakeMatcher( 674 new IsConstantMatcher<float>(IrOpcode::kFloat32Constant, value_matcher)); 675 } 676 677 678 Matcher<Node*> IsFloat64Constant(const Matcher<double>& value_matcher) { 679 return MakeMatcher( 680 new IsConstantMatcher<double>(IrOpcode::kFloat64Constant, value_matcher)); 681 } 682 683 684 Matcher<Node*> IsNumberConstant(const Matcher<double>& value_matcher) { 685 return MakeMatcher( 686 new IsConstantMatcher<double>(IrOpcode::kNumberConstant, value_matcher)); 687 } 688 689 690 Matcher<Node*> IsPhi(const Matcher<MachineType>& type_matcher, 691 const Matcher<Node*>& value0_matcher, 692 const Matcher<Node*>& value1_matcher, 693 const Matcher<Node*>& merge_matcher) { 694 return MakeMatcher(new IsPhiMatcher(type_matcher, value0_matcher, 695 value1_matcher, merge_matcher)); 696 } 697 698 699 Matcher<Node*> IsProjection(const Matcher<size_t>& index_matcher, 700 const Matcher<Node*>& base_matcher) { 701 return MakeMatcher(new IsProjectionMatcher(index_matcher, base_matcher)); 702 } 703 704 705 Matcher<Node*> IsCall(const Matcher<CallDescriptor*>& descriptor_matcher, 706 const Matcher<Node*>& value0_matcher, 707 const Matcher<Node*>& value1_matcher, 708 const Matcher<Node*>& value2_matcher, 709 const Matcher<Node*>& value3_matcher, 710 const Matcher<Node*>& effect_matcher, 711 const Matcher<Node*>& control_matcher) { 712 return MakeMatcher(new IsCallMatcher( 713 descriptor_matcher, value0_matcher, value1_matcher, value2_matcher, 714 value3_matcher, effect_matcher, control_matcher)); 715 } 716 717 718 Matcher<Node*> IsLoad(const Matcher<LoadRepresentation>& rep_matcher, 719 const Matcher<Node*>& base_matcher, 720 const Matcher<Node*>& index_matcher, 721 const Matcher<Node*>& effect_matcher) { 722 return MakeMatcher(new IsLoadMatcher(rep_matcher, base_matcher, index_matcher, 723 effect_matcher)); 724 } 725 726 727 Matcher<Node*> IsStore(const Matcher<MachineType>& type_matcher, 728 const Matcher<WriteBarrierKind>& write_barrier_matcher, 729 const Matcher<Node*>& base_matcher, 730 const Matcher<Node*>& index_matcher, 731 const Matcher<Node*>& value_matcher, 732 const Matcher<Node*>& effect_matcher, 733 const Matcher<Node*>& control_matcher) { 734 return MakeMatcher(new IsStoreMatcher( 735 type_matcher, write_barrier_matcher, base_matcher, index_matcher, 736 value_matcher, effect_matcher, control_matcher)); 737 } 738 739 740 #define IS_BINOP_MATCHER(Name) \ 741 Matcher<Node*> Is##Name(const Matcher<Node*>& lhs_matcher, \ 742 const Matcher<Node*>& rhs_matcher) { \ 743 return MakeMatcher( \ 744 new IsBinopMatcher(IrOpcode::k##Name, lhs_matcher, rhs_matcher)); \ 745 } 746 IS_BINOP_MATCHER(NumberLessThan) 747 IS_BINOP_MATCHER(Word32And) 748 IS_BINOP_MATCHER(Word32Sar) 749 IS_BINOP_MATCHER(Word32Shl) 750 IS_BINOP_MATCHER(Word32Ror) 751 IS_BINOP_MATCHER(Word32Equal) 752 IS_BINOP_MATCHER(Word64And) 753 IS_BINOP_MATCHER(Word64Sar) 754 IS_BINOP_MATCHER(Word64Shl) 755 IS_BINOP_MATCHER(Word64Equal) 756 IS_BINOP_MATCHER(Int32AddWithOverflow) 757 IS_BINOP_MATCHER(Int32Mul) 758 IS_BINOP_MATCHER(Uint32LessThanOrEqual) 759 #undef IS_BINOP_MATCHER 760 761 762 #define IS_UNOP_MATCHER(Name) \ 763 Matcher<Node*> Is##Name(const Matcher<Node*>& input_matcher) { \ 764 return MakeMatcher(new IsUnopMatcher(IrOpcode::k##Name, input_matcher)); \ 765 } 766 IS_UNOP_MATCHER(ChangeFloat64ToInt32) 767 IS_UNOP_MATCHER(ChangeFloat64ToUint32) 768 IS_UNOP_MATCHER(ChangeInt32ToFloat64) 769 IS_UNOP_MATCHER(ChangeInt32ToInt64) 770 IS_UNOP_MATCHER(ChangeUint32ToFloat64) 771 IS_UNOP_MATCHER(ChangeUint32ToUint64) 772 IS_UNOP_MATCHER(TruncateFloat64ToInt32) 773 IS_UNOP_MATCHER(TruncateInt64ToInt32) 774 IS_UNOP_MATCHER(Float64Sqrt) 775 #undef IS_UNOP_MATCHER 776 777 } // namespace compiler 778 } // namespace internal 779 } // namespace v8 780