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