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