Home | History | Annotate | Download | only in compiler
      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