deps: update v8 to 4.3.61.21
[platform/upstream/nodejs.git] / deps / v8 / test / unittests / compiler / node-test-utils.cc
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 "src/assembler.h"
8 #include "src/compiler/node-properties.h"
9 #include "src/compiler/simplified-operator.h"
10 #include "src/unique.h"
11
12 using testing::_;
13 using testing::MakeMatcher;
14 using testing::MatcherInterface;
15 using testing::MatchResultListener;
16 using testing::StringMatchResultListener;
17
18 namespace v8 {
19 namespace internal {
20 namespace compiler {
21
22 namespace {
23
24 template <typename T>
25 bool PrintMatchAndExplain(const T& value, const char* value_name,
26                           const Matcher<T>& value_matcher,
27                           MatchResultListener* listener) {
28   StringMatchResultListener value_listener;
29   if (!value_matcher.MatchAndExplain(value, &value_listener)) {
30     *listener << "whose " << value_name << " " << value << " doesn't match";
31     if (value_listener.str() != "") {
32       *listener << ", " << value_listener.str();
33     }
34     return false;
35   }
36   return true;
37 }
38
39
40 class NodeMatcher : public MatcherInterface<Node*> {
41  public:
42   explicit NodeMatcher(IrOpcode::Value opcode) : opcode_(opcode) {}
43
44   void DescribeTo(std::ostream* os) const OVERRIDE {
45     *os << "is a " << IrOpcode::Mnemonic(opcode_) << " node";
46   }
47
48   bool MatchAndExplain(Node* node,
49                        MatchResultListener* listener) const OVERRIDE {
50     if (node == NULL) {
51       *listener << "which is NULL";
52       return false;
53     }
54     if (node->opcode() != opcode_) {
55       *listener << "whose opcode is " << IrOpcode::Mnemonic(node->opcode())
56                 << " but should have been " << IrOpcode::Mnemonic(opcode_);
57       return false;
58     }
59     return true;
60   }
61
62  private:
63   const IrOpcode::Value opcode_;
64 };
65
66
67 class IsBranchMatcher FINAL : public NodeMatcher {
68  public:
69   IsBranchMatcher(const Matcher<Node*>& value_matcher,
70                   const Matcher<Node*>& control_matcher)
71       : NodeMatcher(IrOpcode::kBranch),
72         value_matcher_(value_matcher),
73         control_matcher_(control_matcher) {}
74
75   void DescribeTo(std::ostream* os) const FINAL {
76     NodeMatcher::DescribeTo(os);
77     *os << " whose value (";
78     value_matcher_.DescribeTo(os);
79     *os << ") and control (";
80     control_matcher_.DescribeTo(os);
81     *os << ")";
82   }
83
84   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
85     return (NodeMatcher::MatchAndExplain(node, listener) &&
86             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
87                                  "value", value_matcher_, listener) &&
88             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
89                                  "control", control_matcher_, listener));
90   }
91
92  private:
93   const Matcher<Node*> value_matcher_;
94   const Matcher<Node*> control_matcher_;
95 };
96
97
98 class IsSwitchMatcher FINAL : public NodeMatcher {
99  public:
100   IsSwitchMatcher(const Matcher<Node*>& value_matcher,
101                   const Matcher<Node*>& control_matcher)
102       : NodeMatcher(IrOpcode::kSwitch),
103         value_matcher_(value_matcher),
104         control_matcher_(control_matcher) {}
105
106   void DescribeTo(std::ostream* os) const FINAL {
107     NodeMatcher::DescribeTo(os);
108     *os << " whose value (";
109     value_matcher_.DescribeTo(os);
110     *os << ") and control (";
111     control_matcher_.DescribeTo(os);
112     *os << ")";
113   }
114
115   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
116     return (NodeMatcher::MatchAndExplain(node, listener) &&
117             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
118                                  "value", value_matcher_, listener) &&
119             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
120                                  "control", control_matcher_, listener));
121   }
122
123  private:
124   const Matcher<Node*> value_matcher_;
125   const Matcher<Node*> control_matcher_;
126 };
127
128
129 class IsIfValueMatcher FINAL : public NodeMatcher {
130  public:
131   IsIfValueMatcher(const Matcher<int32_t>& value_matcher,
132                    const Matcher<Node*>& control_matcher)
133       : NodeMatcher(IrOpcode::kIfValue),
134         value_matcher_(value_matcher),
135         control_matcher_(control_matcher) {}
136
137   void DescribeTo(std::ostream* os) const FINAL {
138     NodeMatcher::DescribeTo(os);
139     *os << " whose value (";
140     value_matcher_.DescribeTo(os);
141     *os << ") and control (";
142     control_matcher_.DescribeTo(os);
143     *os << ")";
144   }
145
146   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
147     return (NodeMatcher::MatchAndExplain(node, listener) &&
148             PrintMatchAndExplain(OpParameter<int32_t>(node->op()), "value",
149                                  value_matcher_, listener) &&
150             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
151                                  "control", control_matcher_, listener));
152   }
153
154  private:
155   const Matcher<int32_t> value_matcher_;
156   const Matcher<Node*> control_matcher_;
157 };
158
159
160 class IsControl1Matcher FINAL : public NodeMatcher {
161  public:
162   IsControl1Matcher(IrOpcode::Value opcode,
163                     const Matcher<Node*>& control_matcher)
164       : NodeMatcher(opcode), control_matcher_(control_matcher) {}
165
166   void DescribeTo(std::ostream* os) const FINAL {
167     NodeMatcher::DescribeTo(os);
168     *os << " whose control (";
169     control_matcher_.DescribeTo(os);
170     *os << ")";
171   }
172
173   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
174     return (NodeMatcher::MatchAndExplain(node, listener) &&
175             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
176                                  "control", control_matcher_, listener));
177   }
178
179  private:
180   const Matcher<Node*> control_matcher_;
181 };
182
183
184 class IsControl2Matcher FINAL : public NodeMatcher {
185  public:
186   IsControl2Matcher(IrOpcode::Value opcode,
187                     const Matcher<Node*>& control0_matcher,
188                     const Matcher<Node*>& control1_matcher)
189       : NodeMatcher(opcode),
190         control0_matcher_(control0_matcher),
191         control1_matcher_(control1_matcher) {}
192
193   void DescribeTo(std::ostream* os) const FINAL {
194     NodeMatcher::DescribeTo(os);
195     *os << " whose control0 (";
196     control0_matcher_.DescribeTo(os);
197     *os << ") and control1 (";
198     control1_matcher_.DescribeTo(os);
199     *os << ")";
200   }
201
202   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
203     return (NodeMatcher::MatchAndExplain(node, listener) &&
204             PrintMatchAndExplain(NodeProperties::GetControlInput(node, 0),
205                                  "control0", control0_matcher_, listener) &&
206             PrintMatchAndExplain(NodeProperties::GetControlInput(node, 1),
207                                  "control1", control1_matcher_, listener));
208   }
209
210  private:
211   const Matcher<Node*> control0_matcher_;
212   const Matcher<Node*> control1_matcher_;
213 };
214
215
216 class IsControl3Matcher FINAL : public NodeMatcher {
217  public:
218   IsControl3Matcher(IrOpcode::Value opcode,
219                     const Matcher<Node*>& control0_matcher,
220                     const Matcher<Node*>& control1_matcher,
221                     const Matcher<Node*>& control2_matcher)
222       : NodeMatcher(opcode),
223         control0_matcher_(control0_matcher),
224         control1_matcher_(control1_matcher),
225         control2_matcher_(control2_matcher) {}
226
227   void DescribeTo(std::ostream* os) const FINAL {
228     NodeMatcher::DescribeTo(os);
229     *os << " whose control0 (";
230     control0_matcher_.DescribeTo(os);
231     *os << ") and control1 (";
232     control1_matcher_.DescribeTo(os);
233     *os << ") and control2 (";
234     control2_matcher_.DescribeTo(os);
235     *os << ")";
236   }
237
238   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
239     return (NodeMatcher::MatchAndExplain(node, listener) &&
240             PrintMatchAndExplain(NodeProperties::GetControlInput(node, 0),
241                                  "control0", control0_matcher_, listener) &&
242             PrintMatchAndExplain(NodeProperties::GetControlInput(node, 1),
243                                  "control1", control1_matcher_, listener) &&
244             PrintMatchAndExplain(NodeProperties::GetControlInput(node, 2),
245                                  "control2", control2_matcher_, listener));
246   }
247
248  private:
249   const Matcher<Node*> control0_matcher_;
250   const Matcher<Node*> control1_matcher_;
251   const Matcher<Node*> control2_matcher_;
252 };
253
254
255 class IsFinishMatcher FINAL : public NodeMatcher {
256  public:
257   IsFinishMatcher(const Matcher<Node*>& value_matcher,
258                   const Matcher<Node*>& effect_matcher)
259       : NodeMatcher(IrOpcode::kFinish),
260         value_matcher_(value_matcher),
261         effect_matcher_(effect_matcher) {}
262
263   void DescribeTo(std::ostream* os) const FINAL {
264     NodeMatcher::DescribeTo(os);
265     *os << " whose value (";
266     value_matcher_.DescribeTo(os);
267     *os << ") and effect (";
268     effect_matcher_.DescribeTo(os);
269     *os << ")";
270   }
271
272   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
273     return (NodeMatcher::MatchAndExplain(node, listener) &&
274             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
275                                  "value", value_matcher_, listener) &&
276             PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
277                                  effect_matcher_, listener));
278   }
279
280  private:
281   const Matcher<Node*> value_matcher_;
282   const Matcher<Node*> effect_matcher_;
283 };
284
285
286 class IsReturnMatcher FINAL : public NodeMatcher {
287  public:
288   IsReturnMatcher(const Matcher<Node*>& value_matcher,
289                   const Matcher<Node*>& effect_matcher,
290                   const Matcher<Node*>& control_matcher)
291       : NodeMatcher(IrOpcode::kReturn),
292         value_matcher_(value_matcher),
293         effect_matcher_(effect_matcher),
294         control_matcher_(control_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 << ") and control (";
303     control_matcher_.DescribeTo(os);
304     *os << ")";
305   }
306
307   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
308     return (NodeMatcher::MatchAndExplain(node, listener) &&
309             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
310                                  "value", value_matcher_, listener) &&
311             PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
312                                  effect_matcher_, listener) &&
313             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
314                                  "control", control_matcher_, listener));
315   }
316
317  private:
318   const Matcher<Node*> value_matcher_;
319   const Matcher<Node*> effect_matcher_;
320   const Matcher<Node*> control_matcher_;
321 };
322
323
324 template <typename T>
325 class IsConstantMatcher FINAL : public NodeMatcher {
326  public:
327   IsConstantMatcher(IrOpcode::Value opcode, const Matcher<T>& value_matcher)
328       : NodeMatcher(opcode), value_matcher_(value_matcher) {}
329
330   void DescribeTo(std::ostream* os) const FINAL {
331     NodeMatcher::DescribeTo(os);
332     *os << " whose value (";
333     value_matcher_.DescribeTo(os);
334     *os << ")";
335   }
336
337   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
338     return (NodeMatcher::MatchAndExplain(node, listener) &&
339             PrintMatchAndExplain(OpParameter<T>(node), "value", value_matcher_,
340                                  listener));
341   }
342
343  private:
344   const Matcher<T> value_matcher_;
345 };
346
347
348 class IsSelectMatcher FINAL : public NodeMatcher {
349  public:
350   IsSelectMatcher(const Matcher<MachineType>& type_matcher,
351                   const Matcher<Node*>& value0_matcher,
352                   const Matcher<Node*>& value1_matcher,
353                   const Matcher<Node*>& value2_matcher)
354       : NodeMatcher(IrOpcode::kSelect),
355         type_matcher_(type_matcher),
356         value0_matcher_(value0_matcher),
357         value1_matcher_(value1_matcher),
358         value2_matcher_(value2_matcher) {}
359
360   void DescribeTo(std::ostream* os) const FINAL {
361     NodeMatcher::DescribeTo(os);
362     *os << " whose type (";
363     type_matcher_.DescribeTo(os);
364     *os << "), value0 (";
365     value0_matcher_.DescribeTo(os);
366     *os << "), value1 (";
367     value1_matcher_.DescribeTo(os);
368     *os << ") and value2 (";
369     value2_matcher_.DescribeTo(os);
370     *os << ")";
371   }
372
373   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
374     return (NodeMatcher::MatchAndExplain(node, listener) &&
375             PrintMatchAndExplain(OpParameter<MachineType>(node), "type",
376                                  type_matcher_, listener) &&
377             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
378                                  "value0", value0_matcher_, listener) &&
379             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
380                                  "value1", value1_matcher_, listener) &&
381             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2),
382                                  "value2", value2_matcher_, listener));
383   }
384
385  private:
386   const Matcher<MachineType> type_matcher_;
387   const Matcher<Node*> value0_matcher_;
388   const Matcher<Node*> value1_matcher_;
389   const Matcher<Node*> value2_matcher_;
390 };
391
392
393 class IsPhiMatcher FINAL : public NodeMatcher {
394  public:
395   IsPhiMatcher(const Matcher<MachineType>& type_matcher,
396                const Matcher<Node*>& value0_matcher,
397                const Matcher<Node*>& value1_matcher,
398                const Matcher<Node*>& control_matcher)
399       : NodeMatcher(IrOpcode::kPhi),
400         type_matcher_(type_matcher),
401         value0_matcher_(value0_matcher),
402         value1_matcher_(value1_matcher),
403         control_matcher_(control_matcher) {}
404
405   void DescribeTo(std::ostream* os) const FINAL {
406     NodeMatcher::DescribeTo(os);
407     *os << " whose type (";
408     type_matcher_.DescribeTo(os);
409     *os << "), value0 (";
410     value0_matcher_.DescribeTo(os);
411     *os << "), value1 (";
412     value1_matcher_.DescribeTo(os);
413     *os << ") and control (";
414     control_matcher_.DescribeTo(os);
415     *os << ")";
416   }
417
418   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
419     return (NodeMatcher::MatchAndExplain(node, listener) &&
420             PrintMatchAndExplain(OpParameter<MachineType>(node), "type",
421                                  type_matcher_, listener) &&
422             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
423                                  "value0", value0_matcher_, listener) &&
424             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
425                                  "value1", value1_matcher_, listener) &&
426             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
427                                  "control", control_matcher_, listener));
428   }
429
430  private:
431   const Matcher<MachineType> type_matcher_;
432   const Matcher<Node*> value0_matcher_;
433   const Matcher<Node*> value1_matcher_;
434   const Matcher<Node*> control_matcher_;
435 };
436
437
438 class IsPhi2Matcher FINAL : public NodeMatcher {
439  public:
440   IsPhi2Matcher(const Matcher<MachineType>& type_matcher,
441                 const Matcher<Node*>& value0_matcher,
442                 const Matcher<Node*>& value1_matcher,
443                 const Matcher<Node*>& value2_matcher,
444                 const Matcher<Node*>& control_matcher)
445       : NodeMatcher(IrOpcode::kPhi),
446         type_matcher_(type_matcher),
447         value0_matcher_(value0_matcher),
448         value1_matcher_(value1_matcher),
449         value2_matcher_(value2_matcher),
450         control_matcher_(control_matcher) {}
451
452   void DescribeTo(std::ostream* os) const FINAL {
453     NodeMatcher::DescribeTo(os);
454     *os << " whose type (";
455     type_matcher_.DescribeTo(os);
456     *os << "), value0 (";
457     value0_matcher_.DescribeTo(os);
458     *os << "), value1 (";
459     value1_matcher_.DescribeTo(os);
460     *os << "), value2 (";
461     value2_matcher_.DescribeTo(os);
462     *os << ") and control (";
463     control_matcher_.DescribeTo(os);
464     *os << ")";
465   }
466
467   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
468     return (NodeMatcher::MatchAndExplain(node, listener) &&
469             PrintMatchAndExplain(OpParameter<MachineType>(node), "type",
470                                  type_matcher_, listener) &&
471             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
472                                  "value0", value0_matcher_, listener) &&
473             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
474                                  "value1", value1_matcher_, listener) &&
475             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2),
476                                  "value2", value2_matcher_, listener) &&
477             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
478                                  "control", control_matcher_, listener));
479   }
480
481  private:
482   const Matcher<MachineType> type_matcher_;
483   const Matcher<Node*> value0_matcher_;
484   const Matcher<Node*> value1_matcher_;
485   const Matcher<Node*> value2_matcher_;
486   const Matcher<Node*> control_matcher_;
487 };
488
489
490 class IsEffectPhiMatcher FINAL : public NodeMatcher {
491  public:
492   IsEffectPhiMatcher(const Matcher<Node*>& effect0_matcher,
493                      const Matcher<Node*>& effect1_matcher,
494                      const Matcher<Node*>& control_matcher)
495       : NodeMatcher(IrOpcode::kEffectPhi),
496         effect0_matcher_(effect0_matcher),
497         effect1_matcher_(effect1_matcher),
498         control_matcher_(control_matcher) {}
499
500   void DescribeTo(std::ostream* os) const FINAL {
501     NodeMatcher::DescribeTo(os);
502     *os << "), effect0 (";
503     effect0_matcher_.DescribeTo(os);
504     *os << "), effect1 (";
505     effect1_matcher_.DescribeTo(os);
506     *os << ") and control (";
507     control_matcher_.DescribeTo(os);
508     *os << ")";
509   }
510
511   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
512     return (NodeMatcher::MatchAndExplain(node, listener) &&
513             PrintMatchAndExplain(NodeProperties::GetEffectInput(node, 0),
514                                  "effect0", effect0_matcher_, listener) &&
515             PrintMatchAndExplain(NodeProperties::GetEffectInput(node, 1),
516                                  "effect1", effect1_matcher_, listener) &&
517             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
518                                  "control", control_matcher_, listener));
519   }
520
521  private:
522   const Matcher<Node*> effect0_matcher_;
523   const Matcher<Node*> effect1_matcher_;
524   const Matcher<Node*> control_matcher_;
525 };
526
527
528 class IsEffectSetMatcher FINAL : public NodeMatcher {
529  public:
530   IsEffectSetMatcher(const Matcher<Node*>& effect0_matcher,
531                      const Matcher<Node*>& effect1_matcher)
532       : NodeMatcher(IrOpcode::kEffectSet),
533         effect0_matcher_(effect0_matcher),
534         effect1_matcher_(effect1_matcher) {}
535
536   void DescribeTo(std::ostream* os) const FINAL {
537     NodeMatcher::DescribeTo(os);
538     *os << "), effect0 (";
539     effect0_matcher_.DescribeTo(os);
540     *os << ") and effect1 (";
541     effect1_matcher_.DescribeTo(os);
542     *os << ")";
543   }
544
545   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
546     if (!NodeMatcher::MatchAndExplain(node, listener)) return false;
547
548     Node* effect0 = NodeProperties::GetEffectInput(node, 0);
549     Node* effect1 = NodeProperties::GetEffectInput(node, 1);
550
551     {
552       // Try matching in the reverse order first.
553       StringMatchResultListener value_listener;
554       if (effect0_matcher_.MatchAndExplain(effect1, &value_listener) &&
555           effect1_matcher_.MatchAndExplain(effect0, &value_listener)) {
556         return true;
557       }
558     }
559
560     return PrintMatchAndExplain(effect0, "effect0", effect0_matcher_,
561                                 listener) &&
562            PrintMatchAndExplain(effect1, "effect1", effect1_matcher_, listener);
563   }
564
565  private:
566   const Matcher<Node*> effect0_matcher_;
567   const Matcher<Node*> effect1_matcher_;
568 };
569
570
571 class IsProjectionMatcher FINAL : public NodeMatcher {
572  public:
573   IsProjectionMatcher(const Matcher<size_t>& index_matcher,
574                       const Matcher<Node*>& base_matcher)
575       : NodeMatcher(IrOpcode::kProjection),
576         index_matcher_(index_matcher),
577         base_matcher_(base_matcher) {}
578
579   void DescribeTo(std::ostream* os) const FINAL {
580     NodeMatcher::DescribeTo(os);
581     *os << " whose index (";
582     index_matcher_.DescribeTo(os);
583     *os << ") and base (";
584     base_matcher_.DescribeTo(os);
585     *os << ")";
586   }
587
588   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
589     return (NodeMatcher::MatchAndExplain(node, listener) &&
590             PrintMatchAndExplain(OpParameter<size_t>(node), "index",
591                                  index_matcher_, listener) &&
592             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
593                                  base_matcher_, listener));
594   }
595
596  private:
597   const Matcher<size_t> index_matcher_;
598   const Matcher<Node*> base_matcher_;
599 };
600
601
602 class IsCall2Matcher FINAL : public NodeMatcher {
603  public:
604   IsCall2Matcher(const Matcher<CallDescriptor*>& descriptor_matcher,
605                  const Matcher<Node*>& value0_matcher,
606                  const Matcher<Node*>& value1_matcher,
607                  const Matcher<Node*>& effect_matcher,
608                  const Matcher<Node*>& control_matcher)
609       : NodeMatcher(IrOpcode::kCall),
610         descriptor_matcher_(descriptor_matcher),
611         value0_matcher_(value0_matcher),
612         value1_matcher_(value1_matcher),
613         effect_matcher_(effect_matcher),
614         control_matcher_(control_matcher) {}
615
616   void DescribeTo(std::ostream* os) const FINAL {
617     NodeMatcher::DescribeTo(os);
618     *os << " whose value0 (";
619     value0_matcher_.DescribeTo(os);
620     *os << ") and value1 (";
621     value1_matcher_.DescribeTo(os);
622     *os << ") and effect (";
623     effect_matcher_.DescribeTo(os);
624     *os << ") and control (";
625     control_matcher_.DescribeTo(os);
626     *os << ")";
627   }
628
629   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
630     return (NodeMatcher::MatchAndExplain(node, listener) &&
631             PrintMatchAndExplain(OpParameter<CallDescriptor*>(node),
632                                  "descriptor", descriptor_matcher_, listener) &&
633             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
634                                  "value0", value0_matcher_, listener) &&
635             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
636                                  "value1", value1_matcher_, listener) &&
637             PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
638                                  effect_matcher_, listener) &&
639             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
640                                  "control", control_matcher_, listener));
641   }
642
643  private:
644   const Matcher<CallDescriptor*> descriptor_matcher_;
645   const Matcher<Node*> value0_matcher_;
646   const Matcher<Node*> value1_matcher_;
647   const Matcher<Node*> effect_matcher_;
648   const Matcher<Node*> control_matcher_;
649 };
650
651
652 class IsCall4Matcher FINAL : public NodeMatcher {
653  public:
654   IsCall4Matcher(const Matcher<CallDescriptor*>& descriptor_matcher,
655                  const Matcher<Node*>& value0_matcher,
656                  const Matcher<Node*>& value1_matcher,
657                  const Matcher<Node*>& value2_matcher,
658                  const Matcher<Node*>& value3_matcher,
659                  const Matcher<Node*>& effect_matcher,
660                  const Matcher<Node*>& control_matcher)
661       : NodeMatcher(IrOpcode::kCall),
662         descriptor_matcher_(descriptor_matcher),
663         value0_matcher_(value0_matcher),
664         value1_matcher_(value1_matcher),
665         value2_matcher_(value2_matcher),
666         value3_matcher_(value3_matcher),
667         effect_matcher_(effect_matcher),
668         control_matcher_(control_matcher) {}
669
670   void DescribeTo(std::ostream* os) const FINAL {
671     NodeMatcher::DescribeTo(os);
672     *os << " whose value0 (";
673     value0_matcher_.DescribeTo(os);
674     *os << ") and value1 (";
675     value1_matcher_.DescribeTo(os);
676     *os << ") and value2 (";
677     value2_matcher_.DescribeTo(os);
678     *os << ") and value3 (";
679     value3_matcher_.DescribeTo(os);
680     *os << ") and effect (";
681     effect_matcher_.DescribeTo(os);
682     *os << ") and control (";
683     control_matcher_.DescribeTo(os);
684     *os << ")";
685   }
686
687   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
688     return (NodeMatcher::MatchAndExplain(node, listener) &&
689             PrintMatchAndExplain(OpParameter<CallDescriptor*>(node),
690                                  "descriptor", descriptor_matcher_, listener) &&
691             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
692                                  "value0", value0_matcher_, listener) &&
693             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
694                                  "value1", value1_matcher_, listener) &&
695             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2),
696                                  "value2", value2_matcher_, listener) &&
697             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 3),
698                                  "value3", value3_matcher_, listener) &&
699             PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
700                                  effect_matcher_, listener) &&
701             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
702                                  "control", control_matcher_, listener));
703   }
704
705  private:
706   const Matcher<CallDescriptor*> descriptor_matcher_;
707   const Matcher<Node*> value0_matcher_;
708   const Matcher<Node*> value1_matcher_;
709   const Matcher<Node*> value2_matcher_;
710   const Matcher<Node*> value3_matcher_;
711   const Matcher<Node*> effect_matcher_;
712   const Matcher<Node*> control_matcher_;
713 };
714
715
716 class IsLoadFieldMatcher FINAL : public NodeMatcher {
717  public:
718   IsLoadFieldMatcher(const Matcher<FieldAccess>& access_matcher,
719                      const Matcher<Node*>& base_matcher,
720                      const Matcher<Node*>& effect_matcher,
721                      const Matcher<Node*>& control_matcher)
722       : NodeMatcher(IrOpcode::kLoadField),
723         access_matcher_(access_matcher),
724         base_matcher_(base_matcher),
725         effect_matcher_(effect_matcher),
726         control_matcher_(control_matcher) {}
727
728   void DescribeTo(std::ostream* os) const FINAL {
729     NodeMatcher::DescribeTo(os);
730     *os << " whose access (";
731     access_matcher_.DescribeTo(os);
732     *os << "), base (";
733     base_matcher_.DescribeTo(os);
734     *os << "), effect (";
735     effect_matcher_.DescribeTo(os);
736     *os << ") and control (";
737     control_matcher_.DescribeTo(os);
738     *os << ")";
739   }
740
741   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
742     return (NodeMatcher::MatchAndExplain(node, listener) &&
743             PrintMatchAndExplain(OpParameter<FieldAccess>(node), "access",
744                                  access_matcher_, listener) &&
745             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
746                                  base_matcher_, listener) &&
747             PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
748                                  effect_matcher_, listener) &&
749             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
750                                  "control", control_matcher_, listener));
751   }
752
753  private:
754   const Matcher<FieldAccess> access_matcher_;
755   const Matcher<Node*> base_matcher_;
756   const Matcher<Node*> effect_matcher_;
757   const Matcher<Node*> control_matcher_;
758 };
759
760
761 class IsStoreFieldMatcher FINAL : public NodeMatcher {
762  public:
763   IsStoreFieldMatcher(const Matcher<FieldAccess>& access_matcher,
764                       const Matcher<Node*>& base_matcher,
765                       const Matcher<Node*>& value_matcher,
766                       const Matcher<Node*>& effect_matcher,
767                       const Matcher<Node*>& control_matcher)
768       : NodeMatcher(IrOpcode::kStoreField),
769         access_matcher_(access_matcher),
770         base_matcher_(base_matcher),
771         value_matcher_(value_matcher),
772         effect_matcher_(effect_matcher),
773         control_matcher_(control_matcher) {}
774
775   void DescribeTo(std::ostream* os) const FINAL {
776     NodeMatcher::DescribeTo(os);
777     *os << " whose access (";
778     access_matcher_.DescribeTo(os);
779     *os << "), base (";
780     base_matcher_.DescribeTo(os);
781     *os << "), value (";
782     value_matcher_.DescribeTo(os);
783     *os << "), effect (";
784     effect_matcher_.DescribeTo(os);
785     *os << ") and control (";
786     control_matcher_.DescribeTo(os);
787     *os << ")";
788   }
789
790   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
791     return (NodeMatcher::MatchAndExplain(node, listener) &&
792             PrintMatchAndExplain(OpParameter<FieldAccess>(node), "access",
793                                  access_matcher_, listener) &&
794             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
795                                  base_matcher_, listener) &&
796             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
797                                  "value", value_matcher_, listener) &&
798             PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
799                                  effect_matcher_, listener) &&
800             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
801                                  "control", control_matcher_, listener));
802   }
803
804  private:
805   const Matcher<FieldAccess> access_matcher_;
806   const Matcher<Node*> base_matcher_;
807   const Matcher<Node*> value_matcher_;
808   const Matcher<Node*> effect_matcher_;
809   const Matcher<Node*> control_matcher_;
810 };
811
812
813 class IsLoadBufferMatcher FINAL : public NodeMatcher {
814  public:
815   IsLoadBufferMatcher(const Matcher<BufferAccess>& access_matcher,
816                       const Matcher<Node*>& buffer_matcher,
817                       const Matcher<Node*>& offset_matcher,
818                       const Matcher<Node*>& length_matcher,
819                       const Matcher<Node*>& effect_matcher,
820                       const Matcher<Node*>& control_matcher)
821       : NodeMatcher(IrOpcode::kLoadBuffer),
822         access_matcher_(access_matcher),
823         buffer_matcher_(buffer_matcher),
824         offset_matcher_(offset_matcher),
825         length_matcher_(length_matcher),
826         effect_matcher_(effect_matcher),
827         control_matcher_(control_matcher) {}
828
829   void DescribeTo(std::ostream* os) const FINAL {
830     NodeMatcher::DescribeTo(os);
831     *os << " whose access (";
832     access_matcher_.DescribeTo(os);
833     *os << "), buffer (";
834     buffer_matcher_.DescribeTo(os);
835     *os << "), offset (";
836     offset_matcher_.DescribeTo(os);
837     *os << "), length (";
838     length_matcher_.DescribeTo(os);
839     *os << "), effect (";
840     effect_matcher_.DescribeTo(os);
841     *os << ") and control (";
842     control_matcher_.DescribeTo(os);
843     *os << ")";
844   }
845
846   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
847     return (NodeMatcher::MatchAndExplain(node, listener) &&
848             PrintMatchAndExplain(BufferAccessOf(node->op()), "access",
849                                  access_matcher_, listener) &&
850             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
851                                  "buffer", buffer_matcher_, listener) &&
852             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
853                                  "offset", offset_matcher_, listener) &&
854             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2),
855                                  "length", length_matcher_, listener) &&
856             PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
857                                  effect_matcher_, listener) &&
858             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
859                                  "control", control_matcher_, listener));
860   }
861
862  private:
863   const Matcher<BufferAccess> access_matcher_;
864   const Matcher<Node*> buffer_matcher_;
865   const Matcher<Node*> offset_matcher_;
866   const Matcher<Node*> length_matcher_;
867   const Matcher<Node*> effect_matcher_;
868   const Matcher<Node*> control_matcher_;
869 };
870
871
872 class IsStoreBufferMatcher FINAL : public NodeMatcher {
873  public:
874   IsStoreBufferMatcher(const Matcher<BufferAccess>& access_matcher,
875                        const Matcher<Node*>& buffer_matcher,
876                        const Matcher<Node*>& offset_matcher,
877                        const Matcher<Node*>& length_matcher,
878                        const Matcher<Node*>& value_matcher,
879                        const Matcher<Node*>& effect_matcher,
880                        const Matcher<Node*>& control_matcher)
881       : NodeMatcher(IrOpcode::kStoreBuffer),
882         access_matcher_(access_matcher),
883         buffer_matcher_(buffer_matcher),
884         offset_matcher_(offset_matcher),
885         length_matcher_(length_matcher),
886         value_matcher_(value_matcher),
887         effect_matcher_(effect_matcher),
888         control_matcher_(control_matcher) {}
889
890   void DescribeTo(std::ostream* os) const FINAL {
891     NodeMatcher::DescribeTo(os);
892     *os << " whose access (";
893     access_matcher_.DescribeTo(os);
894     *os << "), buffer (";
895     buffer_matcher_.DescribeTo(os);
896     *os << "), offset (";
897     offset_matcher_.DescribeTo(os);
898     *os << "), length (";
899     length_matcher_.DescribeTo(os);
900     *os << "), value (";
901     value_matcher_.DescribeTo(os);
902     *os << "), effect (";
903     effect_matcher_.DescribeTo(os);
904     *os << ") and control (";
905     control_matcher_.DescribeTo(os);
906     *os << ")";
907   }
908
909   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
910     return (NodeMatcher::MatchAndExplain(node, listener) &&
911             PrintMatchAndExplain(BufferAccessOf(node->op()), "access",
912                                  access_matcher_, listener) &&
913             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
914                                  "buffer", buffer_matcher_, listener) &&
915             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
916                                  "offset", offset_matcher_, listener) &&
917             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2),
918                                  "length", length_matcher_, listener) &&
919             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 3),
920                                  "value", value_matcher_, listener) &&
921             PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
922                                  effect_matcher_, listener) &&
923             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
924                                  "control", control_matcher_, listener));
925   }
926
927  private:
928   const Matcher<BufferAccess> access_matcher_;
929   const Matcher<Node*> buffer_matcher_;
930   const Matcher<Node*> offset_matcher_;
931   const Matcher<Node*> length_matcher_;
932   const Matcher<Node*> value_matcher_;
933   const Matcher<Node*> effect_matcher_;
934   const Matcher<Node*> control_matcher_;
935 };
936
937
938 class IsLoadElementMatcher FINAL : public NodeMatcher {
939  public:
940   IsLoadElementMatcher(const Matcher<ElementAccess>& access_matcher,
941                        const Matcher<Node*>& base_matcher,
942                        const Matcher<Node*>& index_matcher,
943                        const Matcher<Node*>& effect_matcher,
944                        const Matcher<Node*>& control_matcher)
945       : NodeMatcher(IrOpcode::kLoadElement),
946         access_matcher_(access_matcher),
947         base_matcher_(base_matcher),
948         index_matcher_(index_matcher),
949         effect_matcher_(effect_matcher),
950         control_matcher_(control_matcher) {}
951
952   void DescribeTo(std::ostream* os) const FINAL {
953     NodeMatcher::DescribeTo(os);
954     *os << " whose access (";
955     access_matcher_.DescribeTo(os);
956     *os << "), base (";
957     base_matcher_.DescribeTo(os);
958     *os << "), index (";
959     index_matcher_.DescribeTo(os);
960     *os << "), effect (";
961     effect_matcher_.DescribeTo(os);
962     *os << ") and control (";
963     control_matcher_.DescribeTo(os);
964     *os << ")";
965   }
966
967   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
968     return (NodeMatcher::MatchAndExplain(node, listener) &&
969             PrintMatchAndExplain(OpParameter<ElementAccess>(node), "access",
970                                  access_matcher_, listener) &&
971             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
972                                  base_matcher_, listener) &&
973             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
974                                  "index", index_matcher_, listener) &&
975             PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
976                                  effect_matcher_, listener) &&
977             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
978                                  "control", control_matcher_, listener));
979   }
980
981  private:
982   const Matcher<ElementAccess> access_matcher_;
983   const Matcher<Node*> base_matcher_;
984   const Matcher<Node*> index_matcher_;
985   const Matcher<Node*> effect_matcher_;
986   const Matcher<Node*> control_matcher_;
987 };
988
989
990 class IsStoreElementMatcher FINAL : public NodeMatcher {
991  public:
992   IsStoreElementMatcher(const Matcher<ElementAccess>& access_matcher,
993                         const Matcher<Node*>& base_matcher,
994                         const Matcher<Node*>& index_matcher,
995                         const Matcher<Node*>& value_matcher,
996                         const Matcher<Node*>& effect_matcher,
997                         const Matcher<Node*>& control_matcher)
998       : NodeMatcher(IrOpcode::kStoreElement),
999         access_matcher_(access_matcher),
1000         base_matcher_(base_matcher),
1001         index_matcher_(index_matcher),
1002         value_matcher_(value_matcher),
1003         effect_matcher_(effect_matcher),
1004         control_matcher_(control_matcher) {}
1005
1006   void DescribeTo(std::ostream* os) const FINAL {
1007     NodeMatcher::DescribeTo(os);
1008     *os << " whose access (";
1009     access_matcher_.DescribeTo(os);
1010     *os << "), base (";
1011     base_matcher_.DescribeTo(os);
1012     *os << "), index (";
1013     index_matcher_.DescribeTo(os);
1014     *os << "), value (";
1015     value_matcher_.DescribeTo(os);
1016     *os << "), effect (";
1017     effect_matcher_.DescribeTo(os);
1018     *os << ") and control (";
1019     control_matcher_.DescribeTo(os);
1020     *os << ")";
1021   }
1022
1023   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
1024     return (NodeMatcher::MatchAndExplain(node, listener) &&
1025             PrintMatchAndExplain(OpParameter<ElementAccess>(node), "access",
1026                                  access_matcher_, listener) &&
1027             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
1028                                  base_matcher_, listener) &&
1029             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
1030                                  "index", index_matcher_, listener) &&
1031             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2),
1032                                  "value", value_matcher_, listener) &&
1033             PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
1034                                  effect_matcher_, listener) &&
1035             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
1036                                  "control", control_matcher_, listener));
1037   }
1038
1039  private:
1040   const Matcher<ElementAccess> access_matcher_;
1041   const Matcher<Node*> base_matcher_;
1042   const Matcher<Node*> index_matcher_;
1043   const Matcher<Node*> value_matcher_;
1044   const Matcher<Node*> effect_matcher_;
1045   const Matcher<Node*> control_matcher_;
1046 };
1047
1048
1049 class IsLoadMatcher FINAL : public NodeMatcher {
1050  public:
1051   IsLoadMatcher(const Matcher<LoadRepresentation>& rep_matcher,
1052                 const Matcher<Node*>& base_matcher,
1053                 const Matcher<Node*>& index_matcher,
1054                 const Matcher<Node*>& effect_matcher,
1055                 const Matcher<Node*>& control_matcher)
1056       : NodeMatcher(IrOpcode::kLoad),
1057         rep_matcher_(rep_matcher),
1058         base_matcher_(base_matcher),
1059         index_matcher_(index_matcher),
1060         effect_matcher_(effect_matcher),
1061         control_matcher_(control_matcher) {}
1062
1063   void DescribeTo(std::ostream* os) const FINAL {
1064     NodeMatcher::DescribeTo(os);
1065     *os << " whose rep (";
1066     rep_matcher_.DescribeTo(os);
1067     *os << "), base (";
1068     base_matcher_.DescribeTo(os);
1069     *os << "), index (";
1070     index_matcher_.DescribeTo(os);
1071     *os << "), effect (";
1072     effect_matcher_.DescribeTo(os);
1073     *os << ") and control (";
1074     control_matcher_.DescribeTo(os);
1075     *os << ")";
1076   }
1077
1078   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
1079     return (NodeMatcher::MatchAndExplain(node, listener) &&
1080             PrintMatchAndExplain(OpParameter<LoadRepresentation>(node), "rep",
1081                                  rep_matcher_, listener) &&
1082             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
1083                                  base_matcher_, listener) &&
1084             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
1085                                  "index", index_matcher_, listener) &&
1086             PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
1087                                  effect_matcher_, listener) &&
1088             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
1089                                  "control", control_matcher_, listener));
1090   }
1091
1092  private:
1093   const Matcher<LoadRepresentation> rep_matcher_;
1094   const Matcher<Node*> base_matcher_;
1095   const Matcher<Node*> index_matcher_;
1096   const Matcher<Node*> effect_matcher_;
1097   const Matcher<Node*> control_matcher_;
1098 };
1099
1100
1101 class IsToNumberMatcher FINAL : public NodeMatcher {
1102  public:
1103   IsToNumberMatcher(const Matcher<Node*>& base_matcher,
1104                     const Matcher<Node*>& context_matcher,
1105                     const Matcher<Node*>& effect_matcher,
1106                     const Matcher<Node*>& control_matcher)
1107       : NodeMatcher(IrOpcode::kJSToNumber),
1108         base_matcher_(base_matcher),
1109         context_matcher_(context_matcher),
1110         effect_matcher_(effect_matcher),
1111         control_matcher_(control_matcher) {}
1112
1113   void DescribeTo(std::ostream* os) const FINAL {
1114     NodeMatcher::DescribeTo(os);
1115     *os << " whose base (";
1116     base_matcher_.DescribeTo(os);
1117     *os << "), context (";
1118     context_matcher_.DescribeTo(os);
1119     *os << "), effect (";
1120     effect_matcher_.DescribeTo(os);
1121     *os << ") and control (";
1122     control_matcher_.DescribeTo(os);
1123     *os << ")";
1124   }
1125
1126   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
1127     return (NodeMatcher::MatchAndExplain(node, listener) &&
1128             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
1129                                  base_matcher_, listener) &&
1130             PrintMatchAndExplain(NodeProperties::GetContextInput(node),
1131                                  "context", context_matcher_, listener) &&
1132             PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
1133                                  effect_matcher_, listener) &&
1134             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
1135                                  "control", control_matcher_, listener));
1136   }
1137
1138  private:
1139   const Matcher<Node*> base_matcher_;
1140   const Matcher<Node*> context_matcher_;
1141   const Matcher<Node*> effect_matcher_;
1142   const Matcher<Node*> control_matcher_;
1143 };
1144
1145
1146 class IsStoreMatcher FINAL : public NodeMatcher {
1147  public:
1148   IsStoreMatcher(const Matcher<StoreRepresentation>& rep_matcher,
1149                  const Matcher<Node*>& base_matcher,
1150                  const Matcher<Node*>& index_matcher,
1151                  const Matcher<Node*>& value_matcher,
1152                  const Matcher<Node*>& effect_matcher,
1153                  const Matcher<Node*>& control_matcher)
1154       : NodeMatcher(IrOpcode::kStore),
1155         rep_matcher_(rep_matcher),
1156         base_matcher_(base_matcher),
1157         index_matcher_(index_matcher),
1158         value_matcher_(value_matcher),
1159         effect_matcher_(effect_matcher),
1160         control_matcher_(control_matcher) {}
1161
1162   void DescribeTo(std::ostream* os) const FINAL {
1163     NodeMatcher::DescribeTo(os);
1164     *os << " whose rep (";
1165     rep_matcher_.DescribeTo(os);
1166     *os << "), base (";
1167     base_matcher_.DescribeTo(os);
1168     *os << "), index (";
1169     index_matcher_.DescribeTo(os);
1170     *os << "), value (";
1171     value_matcher_.DescribeTo(os);
1172     *os << "), effect (";
1173     effect_matcher_.DescribeTo(os);
1174     *os << ") and control (";
1175     control_matcher_.DescribeTo(os);
1176     *os << ")";
1177   }
1178
1179   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
1180     return (NodeMatcher::MatchAndExplain(node, listener) &&
1181             PrintMatchAndExplain(OpParameter<StoreRepresentation>(node), "rep",
1182                                  rep_matcher_, listener) &&
1183             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
1184                                  base_matcher_, listener) &&
1185             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
1186                                  "index", index_matcher_, listener) &&
1187             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2),
1188                                  "value", value_matcher_, listener) &&
1189             PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
1190                                  effect_matcher_, listener) &&
1191             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
1192                                  "control", control_matcher_, listener));
1193   }
1194
1195  private:
1196   const Matcher<StoreRepresentation> rep_matcher_;
1197   const Matcher<Node*> base_matcher_;
1198   const Matcher<Node*> index_matcher_;
1199   const Matcher<Node*> value_matcher_;
1200   const Matcher<Node*> effect_matcher_;
1201   const Matcher<Node*> control_matcher_;
1202 };
1203
1204
1205 class IsBinopMatcher FINAL : public NodeMatcher {
1206  public:
1207   IsBinopMatcher(IrOpcode::Value opcode, const Matcher<Node*>& lhs_matcher,
1208                  const Matcher<Node*>& rhs_matcher)
1209       : NodeMatcher(opcode),
1210         lhs_matcher_(lhs_matcher),
1211         rhs_matcher_(rhs_matcher) {}
1212
1213   void DescribeTo(std::ostream* os) const FINAL {
1214     NodeMatcher::DescribeTo(os);
1215     *os << " whose lhs (";
1216     lhs_matcher_.DescribeTo(os);
1217     *os << ") and rhs (";
1218     rhs_matcher_.DescribeTo(os);
1219     *os << ")";
1220   }
1221
1222   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
1223     return (NodeMatcher::MatchAndExplain(node, listener) &&
1224             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "lhs",
1225                                  lhs_matcher_, listener) &&
1226             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "rhs",
1227                                  rhs_matcher_, listener));
1228   }
1229
1230  private:
1231   const Matcher<Node*> lhs_matcher_;
1232   const Matcher<Node*> rhs_matcher_;
1233 };
1234
1235
1236 class IsUnopMatcher FINAL : public NodeMatcher {
1237  public:
1238   IsUnopMatcher(IrOpcode::Value opcode, const Matcher<Node*>& input_matcher)
1239       : NodeMatcher(opcode), input_matcher_(input_matcher) {}
1240
1241   void DescribeTo(std::ostream* os) const FINAL {
1242     NodeMatcher::DescribeTo(os);
1243     *os << " whose input (";
1244     input_matcher_.DescribeTo(os);
1245     *os << ")";
1246   }
1247
1248   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
1249     return (NodeMatcher::MatchAndExplain(node, listener) &&
1250             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
1251                                  "input", input_matcher_, listener));
1252   }
1253
1254  private:
1255   const Matcher<Node*> input_matcher_;
1256 };
1257
1258 }  // namespace
1259
1260
1261 Matcher<Node*> IsAlways() {
1262   return MakeMatcher(new NodeMatcher(IrOpcode::kAlways));
1263 }
1264
1265
1266 Matcher<Node*> IsEnd(const Matcher<Node*>& control_matcher) {
1267   return MakeMatcher(new IsControl1Matcher(IrOpcode::kEnd, control_matcher));
1268 }
1269
1270
1271 Matcher<Node*> IsBranch(const Matcher<Node*>& value_matcher,
1272                         const Matcher<Node*>& control_matcher) {
1273   return MakeMatcher(new IsBranchMatcher(value_matcher, control_matcher));
1274 }
1275
1276
1277 Matcher<Node*> IsMerge(const Matcher<Node*>& control0_matcher,
1278                        const Matcher<Node*>& control1_matcher) {
1279   return MakeMatcher(new IsControl2Matcher(IrOpcode::kMerge, control0_matcher,
1280                                            control1_matcher));
1281 }
1282
1283
1284 Matcher<Node*> IsMerge(const Matcher<Node*>& control0_matcher,
1285                        const Matcher<Node*>& control1_matcher,
1286                        const Matcher<Node*>& control2_matcher) {
1287   return MakeMatcher(new IsControl3Matcher(IrOpcode::kMerge, control0_matcher,
1288                                            control1_matcher, control2_matcher));
1289 }
1290
1291
1292 Matcher<Node*> IsLoop(const Matcher<Node*>& control0_matcher,
1293                       const Matcher<Node*>& control1_matcher) {
1294   return MakeMatcher(new IsControl2Matcher(IrOpcode::kLoop, control0_matcher,
1295                                            control1_matcher));
1296 }
1297
1298
1299 Matcher<Node*> IsLoop(const Matcher<Node*>& control0_matcher,
1300                       const Matcher<Node*>& control1_matcher,
1301                       const Matcher<Node*>& control2_matcher) {
1302   return MakeMatcher(new IsControl3Matcher(IrOpcode::kLoop, control0_matcher,
1303                                            control1_matcher, control2_matcher));
1304 }
1305
1306
1307 Matcher<Node*> IsIfTrue(const Matcher<Node*>& control_matcher) {
1308   return MakeMatcher(new IsControl1Matcher(IrOpcode::kIfTrue, control_matcher));
1309 }
1310
1311
1312 Matcher<Node*> IsIfFalse(const Matcher<Node*>& control_matcher) {
1313   return MakeMatcher(
1314       new IsControl1Matcher(IrOpcode::kIfFalse, control_matcher));
1315 }
1316
1317
1318 Matcher<Node*> IsIfSuccess(const Matcher<Node*>& control_matcher) {
1319   return MakeMatcher(
1320       new IsControl1Matcher(IrOpcode::kIfSuccess, control_matcher));
1321 }
1322
1323
1324 Matcher<Node*> IsSwitch(const Matcher<Node*>& value_matcher,
1325                         const Matcher<Node*>& control_matcher) {
1326   return MakeMatcher(new IsSwitchMatcher(value_matcher, control_matcher));
1327 }
1328
1329
1330 Matcher<Node*> IsIfValue(const Matcher<int32_t>& value_matcher,
1331                          const Matcher<Node*>& control_matcher) {
1332   return MakeMatcher(new IsIfValueMatcher(value_matcher, control_matcher));
1333 }
1334
1335
1336 Matcher<Node*> IsIfDefault(const Matcher<Node*>& control_matcher) {
1337   return MakeMatcher(
1338       new IsControl1Matcher(IrOpcode::kIfDefault, control_matcher));
1339 }
1340
1341
1342 Matcher<Node*> IsValueEffect(const Matcher<Node*>& value_matcher) {
1343   return MakeMatcher(new IsUnopMatcher(IrOpcode::kValueEffect, value_matcher));
1344 }
1345
1346
1347 Matcher<Node*> IsFinish(const Matcher<Node*>& value_matcher,
1348                         const Matcher<Node*>& effect_matcher) {
1349   return MakeMatcher(new IsFinishMatcher(value_matcher, effect_matcher));
1350 }
1351
1352
1353 Matcher<Node*> IsReturn(const Matcher<Node*>& value_matcher,
1354                         const Matcher<Node*>& effect_matcher,
1355                         const Matcher<Node*>& control_matcher) {
1356   return MakeMatcher(
1357       new IsReturnMatcher(value_matcher, effect_matcher, control_matcher));
1358 }
1359
1360
1361 Matcher<Node*> IsExternalConstant(
1362     const Matcher<ExternalReference>& value_matcher) {
1363   return MakeMatcher(new IsConstantMatcher<ExternalReference>(
1364       IrOpcode::kExternalConstant, value_matcher));
1365 }
1366
1367
1368 Matcher<Node*> IsHeapConstant(
1369     const Matcher<Unique<HeapObject> >& value_matcher) {
1370   return MakeMatcher(new IsConstantMatcher<Unique<HeapObject> >(
1371       IrOpcode::kHeapConstant, value_matcher));
1372 }
1373
1374
1375 Matcher<Node*> IsInt32Constant(const Matcher<int32_t>& value_matcher) {
1376   return MakeMatcher(
1377       new IsConstantMatcher<int32_t>(IrOpcode::kInt32Constant, value_matcher));
1378 }
1379
1380
1381 Matcher<Node*> IsInt64Constant(const Matcher<int64_t>& value_matcher) {
1382   return MakeMatcher(
1383       new IsConstantMatcher<int64_t>(IrOpcode::kInt64Constant, value_matcher));
1384 }
1385
1386
1387 Matcher<Node*> IsFloat32Constant(const Matcher<float>& value_matcher) {
1388   return MakeMatcher(
1389       new IsConstantMatcher<float>(IrOpcode::kFloat32Constant, value_matcher));
1390 }
1391
1392
1393 Matcher<Node*> IsFloat64Constant(const Matcher<double>& value_matcher) {
1394   return MakeMatcher(
1395       new IsConstantMatcher<double>(IrOpcode::kFloat64Constant, value_matcher));
1396 }
1397
1398
1399 Matcher<Node*> IsNumberConstant(const Matcher<double>& value_matcher) {
1400   return MakeMatcher(
1401       new IsConstantMatcher<double>(IrOpcode::kNumberConstant, value_matcher));
1402 }
1403
1404
1405 Matcher<Node*> IsSelect(const Matcher<MachineType>& type_matcher,
1406                         const Matcher<Node*>& value0_matcher,
1407                         const Matcher<Node*>& value1_matcher,
1408                         const Matcher<Node*>& value2_matcher) {
1409   return MakeMatcher(new IsSelectMatcher(type_matcher, value0_matcher,
1410                                          value1_matcher, value2_matcher));
1411 }
1412
1413
1414 Matcher<Node*> IsPhi(const Matcher<MachineType>& type_matcher,
1415                      const Matcher<Node*>& value0_matcher,
1416                      const Matcher<Node*>& value1_matcher,
1417                      const Matcher<Node*>& merge_matcher) {
1418   return MakeMatcher(new IsPhiMatcher(type_matcher, value0_matcher,
1419                                       value1_matcher, merge_matcher));
1420 }
1421
1422
1423 Matcher<Node*> IsPhi(const Matcher<MachineType>& type_matcher,
1424                      const Matcher<Node*>& value0_matcher,
1425                      const Matcher<Node*>& value1_matcher,
1426                      const Matcher<Node*>& value2_matcher,
1427                      const Matcher<Node*>& merge_matcher) {
1428   return MakeMatcher(new IsPhi2Matcher(type_matcher, value0_matcher,
1429                                        value1_matcher, value2_matcher,
1430                                        merge_matcher));
1431 }
1432
1433
1434 Matcher<Node*> IsEffectPhi(const Matcher<Node*>& effect0_matcher,
1435                            const Matcher<Node*>& effect1_matcher,
1436                            const Matcher<Node*>& merge_matcher) {
1437   return MakeMatcher(
1438       new IsEffectPhiMatcher(effect0_matcher, effect1_matcher, merge_matcher));
1439 }
1440
1441
1442 Matcher<Node*> IsEffectSet(const Matcher<Node*>& effect0_matcher,
1443                            const Matcher<Node*>& effect1_matcher) {
1444   return MakeMatcher(new IsEffectSetMatcher(effect0_matcher, effect1_matcher));
1445 }
1446
1447
1448 Matcher<Node*> IsProjection(const Matcher<size_t>& index_matcher,
1449                             const Matcher<Node*>& base_matcher) {
1450   return MakeMatcher(new IsProjectionMatcher(index_matcher, base_matcher));
1451 }
1452
1453
1454 Matcher<Node*> IsCall(const Matcher<CallDescriptor*>& descriptor_matcher,
1455                       const Matcher<Node*>& value0_matcher,
1456                       const Matcher<Node*>& value1_matcher,
1457                       const Matcher<Node*>& effect_matcher,
1458                       const Matcher<Node*>& control_matcher) {
1459   return MakeMatcher(new IsCall2Matcher(descriptor_matcher, value0_matcher,
1460                                         value1_matcher, effect_matcher,
1461                                         control_matcher));
1462 }
1463
1464
1465 Matcher<Node*> IsCall(const Matcher<CallDescriptor*>& descriptor_matcher,
1466                       const Matcher<Node*>& value0_matcher,
1467                       const Matcher<Node*>& value1_matcher,
1468                       const Matcher<Node*>& value2_matcher,
1469                       const Matcher<Node*>& value3_matcher,
1470                       const Matcher<Node*>& effect_matcher,
1471                       const Matcher<Node*>& control_matcher) {
1472   return MakeMatcher(new IsCall4Matcher(
1473       descriptor_matcher, value0_matcher, value1_matcher, value2_matcher,
1474       value3_matcher, effect_matcher, control_matcher));
1475 }
1476
1477
1478 Matcher<Node*> IsLoadField(const Matcher<FieldAccess>& access_matcher,
1479                            const Matcher<Node*>& base_matcher,
1480                            const Matcher<Node*>& effect_matcher,
1481                            const Matcher<Node*>& control_matcher) {
1482   return MakeMatcher(new IsLoadFieldMatcher(access_matcher, base_matcher,
1483                                             effect_matcher, control_matcher));
1484 }
1485
1486
1487 Matcher<Node*> IsStoreField(const Matcher<FieldAccess>& access_matcher,
1488                             const Matcher<Node*>& base_matcher,
1489                             const Matcher<Node*>& value_matcher,
1490                             const Matcher<Node*>& effect_matcher,
1491                             const Matcher<Node*>& control_matcher) {
1492   return MakeMatcher(new IsStoreFieldMatcher(access_matcher, base_matcher,
1493                                              value_matcher, effect_matcher,
1494                                              control_matcher));
1495 }
1496
1497
1498 Matcher<Node*> IsLoadBuffer(const Matcher<BufferAccess>& access_matcher,
1499                             const Matcher<Node*>& buffer_matcher,
1500                             const Matcher<Node*>& offset_matcher,
1501                             const Matcher<Node*>& length_matcher,
1502                             const Matcher<Node*>& effect_matcher,
1503                             const Matcher<Node*>& control_matcher) {
1504   return MakeMatcher(new IsLoadBufferMatcher(access_matcher, buffer_matcher,
1505                                              offset_matcher, length_matcher,
1506                                              effect_matcher, control_matcher));
1507 }
1508
1509
1510 Matcher<Node*> IsStoreBuffer(const Matcher<BufferAccess>& access_matcher,
1511                              const Matcher<Node*>& buffer_matcher,
1512                              const Matcher<Node*>& offset_matcher,
1513                              const Matcher<Node*>& length_matcher,
1514                              const Matcher<Node*>& value_matcher,
1515                              const Matcher<Node*>& effect_matcher,
1516                              const Matcher<Node*>& control_matcher) {
1517   return MakeMatcher(new IsStoreBufferMatcher(
1518       access_matcher, buffer_matcher, offset_matcher, length_matcher,
1519       value_matcher, effect_matcher, control_matcher));
1520 }
1521
1522
1523 Matcher<Node*> IsLoadElement(const Matcher<ElementAccess>& access_matcher,
1524                              const Matcher<Node*>& base_matcher,
1525                              const Matcher<Node*>& index_matcher,
1526                              const Matcher<Node*>& effect_matcher,
1527                              const Matcher<Node*>& control_matcher) {
1528   return MakeMatcher(new IsLoadElementMatcher(access_matcher, base_matcher,
1529                                               index_matcher, effect_matcher,
1530                                               control_matcher));
1531 }
1532
1533
1534 Matcher<Node*> IsStoreElement(const Matcher<ElementAccess>& access_matcher,
1535                               const Matcher<Node*>& base_matcher,
1536                               const Matcher<Node*>& index_matcher,
1537                               const Matcher<Node*>& value_matcher,
1538                               const Matcher<Node*>& effect_matcher,
1539                               const Matcher<Node*>& control_matcher) {
1540   return MakeMatcher(new IsStoreElementMatcher(
1541       access_matcher, base_matcher, index_matcher, value_matcher,
1542       effect_matcher, control_matcher));
1543 }
1544
1545
1546 Matcher<Node*> IsLoad(const Matcher<LoadRepresentation>& rep_matcher,
1547                       const Matcher<Node*>& base_matcher,
1548                       const Matcher<Node*>& index_matcher,
1549                       const Matcher<Node*>& effect_matcher,
1550                       const Matcher<Node*>& control_matcher) {
1551   return MakeMatcher(new IsLoadMatcher(rep_matcher, base_matcher, index_matcher,
1552                                        effect_matcher, control_matcher));
1553 }
1554
1555
1556 Matcher<Node*> IsToNumber(const Matcher<Node*>& base_matcher,
1557                           const Matcher<Node*>& context_matcher,
1558                           const Matcher<Node*>& effect_matcher,
1559                           const Matcher<Node*>& control_matcher) {
1560   return MakeMatcher(new IsToNumberMatcher(base_matcher, context_matcher,
1561                                            effect_matcher, control_matcher));
1562 }
1563
1564
1565 Matcher<Node*> IsStore(const Matcher<StoreRepresentation>& rep_matcher,
1566                        const Matcher<Node*>& base_matcher,
1567                        const Matcher<Node*>& index_matcher,
1568                        const Matcher<Node*>& value_matcher,
1569                        const Matcher<Node*>& effect_matcher,
1570                        const Matcher<Node*>& control_matcher) {
1571   return MakeMatcher(new IsStoreMatcher(rep_matcher, base_matcher,
1572                                         index_matcher, value_matcher,
1573                                         effect_matcher, control_matcher));
1574 }
1575
1576
1577 #define IS_BINOP_MATCHER(Name)                                            \
1578   Matcher<Node*> Is##Name(const Matcher<Node*>& lhs_matcher,              \
1579                           const Matcher<Node*>& rhs_matcher) {            \
1580     return MakeMatcher(                                                   \
1581         new IsBinopMatcher(IrOpcode::k##Name, lhs_matcher, rhs_matcher)); \
1582   }
1583 IS_BINOP_MATCHER(NumberEqual)
1584 IS_BINOP_MATCHER(NumberLessThan)
1585 IS_BINOP_MATCHER(NumberSubtract)
1586 IS_BINOP_MATCHER(NumberMultiply)
1587 IS_BINOP_MATCHER(Word32And)
1588 IS_BINOP_MATCHER(Word32Sar)
1589 IS_BINOP_MATCHER(Word32Shl)
1590 IS_BINOP_MATCHER(Word32Shr)
1591 IS_BINOP_MATCHER(Word32Ror)
1592 IS_BINOP_MATCHER(Word32Equal)
1593 IS_BINOP_MATCHER(Word64And)
1594 IS_BINOP_MATCHER(Word64Sar)
1595 IS_BINOP_MATCHER(Word64Shl)
1596 IS_BINOP_MATCHER(Word64Equal)
1597 IS_BINOP_MATCHER(Int32AddWithOverflow)
1598 IS_BINOP_MATCHER(Int32Add)
1599 IS_BINOP_MATCHER(Int32Sub)
1600 IS_BINOP_MATCHER(Int32Mul)
1601 IS_BINOP_MATCHER(Int32MulHigh)
1602 IS_BINOP_MATCHER(Int32LessThan)
1603 IS_BINOP_MATCHER(Uint32LessThan)
1604 IS_BINOP_MATCHER(Uint32LessThanOrEqual)
1605 IS_BINOP_MATCHER(Float64Max)
1606 IS_BINOP_MATCHER(Float64Min)
1607 IS_BINOP_MATCHER(Float64Sub)
1608 IS_BINOP_MATCHER(Float64InsertLowWord32)
1609 IS_BINOP_MATCHER(Float64InsertHighWord32)
1610 #undef IS_BINOP_MATCHER
1611
1612
1613 #define IS_UNOP_MATCHER(Name)                                                \
1614   Matcher<Node*> Is##Name(const Matcher<Node*>& input_matcher) {             \
1615     return MakeMatcher(new IsUnopMatcher(IrOpcode::k##Name, input_matcher)); \
1616   }
1617 IS_UNOP_MATCHER(BooleanNot)
1618 IS_UNOP_MATCHER(ChangeFloat64ToInt32)
1619 IS_UNOP_MATCHER(ChangeFloat64ToUint32)
1620 IS_UNOP_MATCHER(ChangeInt32ToFloat64)
1621 IS_UNOP_MATCHER(ChangeInt32ToInt64)
1622 IS_UNOP_MATCHER(ChangeUint32ToFloat64)
1623 IS_UNOP_MATCHER(ChangeUint32ToUint64)
1624 IS_UNOP_MATCHER(TruncateFloat64ToFloat32)
1625 IS_UNOP_MATCHER(TruncateFloat64ToInt32)
1626 IS_UNOP_MATCHER(TruncateInt64ToInt32)
1627 IS_UNOP_MATCHER(Float64Sqrt)
1628 IS_UNOP_MATCHER(Float64RoundDown)
1629 IS_UNOP_MATCHER(Float64RoundTruncate)
1630 IS_UNOP_MATCHER(Float64RoundTiesAway)
1631 IS_UNOP_MATCHER(Float64ExtractLowWord32)
1632 IS_UNOP_MATCHER(Float64ExtractHighWord32)
1633 IS_UNOP_MATCHER(NumberToInt32)
1634 IS_UNOP_MATCHER(NumberToUint32)
1635 IS_UNOP_MATCHER(ObjectIsSmi)
1636 IS_UNOP_MATCHER(ObjectIsNonNegativeSmi)
1637 IS_UNOP_MATCHER(Word32Clz)
1638 #undef IS_UNOP_MATCHER
1639
1640 }  // namespace compiler
1641 }  // namespace internal
1642 }  // namespace v8