eccc96227e4e0d4fbb1bd4f6e867d6d23a3a5563
[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     return (NodeMatcher::MatchAndExplain(node, listener) &&
547             PrintMatchAndExplain(NodeProperties::GetEffectInput(node, 0),
548                                  "effect0", effect0_matcher_, listener) &&
549             PrintMatchAndExplain(NodeProperties::GetEffectInput(node, 1),
550                                  "effect1", effect1_matcher_, listener));
551   }
552
553  private:
554   const Matcher<Node*> effect0_matcher_;
555   const Matcher<Node*> effect1_matcher_;
556 };
557
558
559 class IsProjectionMatcher FINAL : public NodeMatcher {
560  public:
561   IsProjectionMatcher(const Matcher<size_t>& index_matcher,
562                       const Matcher<Node*>& base_matcher)
563       : NodeMatcher(IrOpcode::kProjection),
564         index_matcher_(index_matcher),
565         base_matcher_(base_matcher) {}
566
567   void DescribeTo(std::ostream* os) const FINAL {
568     NodeMatcher::DescribeTo(os);
569     *os << " whose index (";
570     index_matcher_.DescribeTo(os);
571     *os << ") and base (";
572     base_matcher_.DescribeTo(os);
573     *os << ")";
574   }
575
576   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
577     return (NodeMatcher::MatchAndExplain(node, listener) &&
578             PrintMatchAndExplain(OpParameter<size_t>(node), "index",
579                                  index_matcher_, listener) &&
580             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
581                                  base_matcher_, listener));
582   }
583
584  private:
585   const Matcher<size_t> index_matcher_;
586   const Matcher<Node*> base_matcher_;
587 };
588
589
590 class IsCall2Matcher FINAL : public NodeMatcher {
591  public:
592   IsCall2Matcher(const Matcher<CallDescriptor*>& descriptor_matcher,
593                  const Matcher<Node*>& value0_matcher,
594                  const Matcher<Node*>& value1_matcher,
595                  const Matcher<Node*>& effect_matcher,
596                  const Matcher<Node*>& control_matcher)
597       : NodeMatcher(IrOpcode::kCall),
598         descriptor_matcher_(descriptor_matcher),
599         value0_matcher_(value0_matcher),
600         value1_matcher_(value1_matcher),
601         effect_matcher_(effect_matcher),
602         control_matcher_(control_matcher) {}
603
604   void DescribeTo(std::ostream* os) const FINAL {
605     NodeMatcher::DescribeTo(os);
606     *os << " whose value0 (";
607     value0_matcher_.DescribeTo(os);
608     *os << ") and value1 (";
609     value1_matcher_.DescribeTo(os);
610     *os << ") and effect (";
611     effect_matcher_.DescribeTo(os);
612     *os << ") and control (";
613     control_matcher_.DescribeTo(os);
614     *os << ")";
615   }
616
617   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
618     return (NodeMatcher::MatchAndExplain(node, listener) &&
619             PrintMatchAndExplain(OpParameter<CallDescriptor*>(node),
620                                  "descriptor", descriptor_matcher_, listener) &&
621             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
622                                  "value0", value0_matcher_, listener) &&
623             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
624                                  "value1", value1_matcher_, listener) &&
625             PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
626                                  effect_matcher_, listener) &&
627             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
628                                  "control", control_matcher_, listener));
629   }
630
631  private:
632   const Matcher<CallDescriptor*> descriptor_matcher_;
633   const Matcher<Node*> value0_matcher_;
634   const Matcher<Node*> value1_matcher_;
635   const Matcher<Node*> effect_matcher_;
636   const Matcher<Node*> control_matcher_;
637 };
638
639
640 class IsCall4Matcher FINAL : public NodeMatcher {
641  public:
642   IsCall4Matcher(const Matcher<CallDescriptor*>& descriptor_matcher,
643                  const Matcher<Node*>& value0_matcher,
644                  const Matcher<Node*>& value1_matcher,
645                  const Matcher<Node*>& value2_matcher,
646                  const Matcher<Node*>& value3_matcher,
647                  const Matcher<Node*>& effect_matcher,
648                  const Matcher<Node*>& control_matcher)
649       : NodeMatcher(IrOpcode::kCall),
650         descriptor_matcher_(descriptor_matcher),
651         value0_matcher_(value0_matcher),
652         value1_matcher_(value1_matcher),
653         value2_matcher_(value2_matcher),
654         value3_matcher_(value3_matcher),
655         effect_matcher_(effect_matcher),
656         control_matcher_(control_matcher) {}
657
658   void DescribeTo(std::ostream* os) const FINAL {
659     NodeMatcher::DescribeTo(os);
660     *os << " whose value0 (";
661     value0_matcher_.DescribeTo(os);
662     *os << ") and value1 (";
663     value1_matcher_.DescribeTo(os);
664     *os << ") and value2 (";
665     value2_matcher_.DescribeTo(os);
666     *os << ") and value3 (";
667     value3_matcher_.DescribeTo(os);
668     *os << ") and effect (";
669     effect_matcher_.DescribeTo(os);
670     *os << ") and control (";
671     control_matcher_.DescribeTo(os);
672     *os << ")";
673   }
674
675   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
676     return (NodeMatcher::MatchAndExplain(node, listener) &&
677             PrintMatchAndExplain(OpParameter<CallDescriptor*>(node),
678                                  "descriptor", descriptor_matcher_, listener) &&
679             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
680                                  "value0", value0_matcher_, listener) &&
681             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
682                                  "value1", value1_matcher_, listener) &&
683             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2),
684                                  "value2", value2_matcher_, listener) &&
685             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 3),
686                                  "value3", value3_matcher_, listener) &&
687             PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
688                                  effect_matcher_, listener) &&
689             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
690                                  "control", control_matcher_, listener));
691   }
692
693  private:
694   const Matcher<CallDescriptor*> descriptor_matcher_;
695   const Matcher<Node*> value0_matcher_;
696   const Matcher<Node*> value1_matcher_;
697   const Matcher<Node*> value2_matcher_;
698   const Matcher<Node*> value3_matcher_;
699   const Matcher<Node*> effect_matcher_;
700   const Matcher<Node*> control_matcher_;
701 };
702
703
704 class IsLoadFieldMatcher FINAL : public NodeMatcher {
705  public:
706   IsLoadFieldMatcher(const Matcher<FieldAccess>& access_matcher,
707                      const Matcher<Node*>& base_matcher,
708                      const Matcher<Node*>& effect_matcher,
709                      const Matcher<Node*>& control_matcher)
710       : NodeMatcher(IrOpcode::kLoadField),
711         access_matcher_(access_matcher),
712         base_matcher_(base_matcher),
713         effect_matcher_(effect_matcher),
714         control_matcher_(control_matcher) {}
715
716   void DescribeTo(std::ostream* os) const FINAL {
717     NodeMatcher::DescribeTo(os);
718     *os << " whose access (";
719     access_matcher_.DescribeTo(os);
720     *os << "), base (";
721     base_matcher_.DescribeTo(os);
722     *os << "), effect (";
723     effect_matcher_.DescribeTo(os);
724     *os << ") and control (";
725     control_matcher_.DescribeTo(os);
726     *os << ")";
727   }
728
729   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
730     return (NodeMatcher::MatchAndExplain(node, listener) &&
731             PrintMatchAndExplain(OpParameter<FieldAccess>(node), "access",
732                                  access_matcher_, listener) &&
733             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
734                                  base_matcher_, listener) &&
735             PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
736                                  effect_matcher_, listener) &&
737             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
738                                  "control", control_matcher_, listener));
739   }
740
741  private:
742   const Matcher<FieldAccess> access_matcher_;
743   const Matcher<Node*> base_matcher_;
744   const Matcher<Node*> effect_matcher_;
745   const Matcher<Node*> control_matcher_;
746 };
747
748
749 class IsStoreFieldMatcher FINAL : public NodeMatcher {
750  public:
751   IsStoreFieldMatcher(const Matcher<FieldAccess>& access_matcher,
752                       const Matcher<Node*>& base_matcher,
753                       const Matcher<Node*>& value_matcher,
754                       const Matcher<Node*>& effect_matcher,
755                       const Matcher<Node*>& control_matcher)
756       : NodeMatcher(IrOpcode::kStoreField),
757         access_matcher_(access_matcher),
758         base_matcher_(base_matcher),
759         value_matcher_(value_matcher),
760         effect_matcher_(effect_matcher),
761         control_matcher_(control_matcher) {}
762
763   void DescribeTo(std::ostream* os) const FINAL {
764     NodeMatcher::DescribeTo(os);
765     *os << " whose access (";
766     access_matcher_.DescribeTo(os);
767     *os << "), base (";
768     base_matcher_.DescribeTo(os);
769     *os << "), value (";
770     value_matcher_.DescribeTo(os);
771     *os << "), effect (";
772     effect_matcher_.DescribeTo(os);
773     *os << ") and control (";
774     control_matcher_.DescribeTo(os);
775     *os << ")";
776   }
777
778   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
779     return (NodeMatcher::MatchAndExplain(node, listener) &&
780             PrintMatchAndExplain(OpParameter<FieldAccess>(node), "access",
781                                  access_matcher_, listener) &&
782             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
783                                  base_matcher_, listener) &&
784             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
785                                  "value", value_matcher_, listener) &&
786             PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
787                                  effect_matcher_, listener) &&
788             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
789                                  "control", control_matcher_, listener));
790   }
791
792  private:
793   const Matcher<FieldAccess> access_matcher_;
794   const Matcher<Node*> base_matcher_;
795   const Matcher<Node*> value_matcher_;
796   const Matcher<Node*> effect_matcher_;
797   const Matcher<Node*> control_matcher_;
798 };
799
800
801 class IsLoadBufferMatcher FINAL : public NodeMatcher {
802  public:
803   IsLoadBufferMatcher(const Matcher<BufferAccess>& access_matcher,
804                       const Matcher<Node*>& buffer_matcher,
805                       const Matcher<Node*>& offset_matcher,
806                       const Matcher<Node*>& length_matcher,
807                       const Matcher<Node*>& effect_matcher,
808                       const Matcher<Node*>& control_matcher)
809       : NodeMatcher(IrOpcode::kLoadBuffer),
810         access_matcher_(access_matcher),
811         buffer_matcher_(buffer_matcher),
812         offset_matcher_(offset_matcher),
813         length_matcher_(length_matcher),
814         effect_matcher_(effect_matcher),
815         control_matcher_(control_matcher) {}
816
817   void DescribeTo(std::ostream* os) const FINAL {
818     NodeMatcher::DescribeTo(os);
819     *os << " whose access (";
820     access_matcher_.DescribeTo(os);
821     *os << "), buffer (";
822     buffer_matcher_.DescribeTo(os);
823     *os << "), offset (";
824     offset_matcher_.DescribeTo(os);
825     *os << "), length (";
826     length_matcher_.DescribeTo(os);
827     *os << "), effect (";
828     effect_matcher_.DescribeTo(os);
829     *os << ") and control (";
830     control_matcher_.DescribeTo(os);
831     *os << ")";
832   }
833
834   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
835     return (NodeMatcher::MatchAndExplain(node, listener) &&
836             PrintMatchAndExplain(BufferAccessOf(node->op()), "access",
837                                  access_matcher_, listener) &&
838             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
839                                  "buffer", buffer_matcher_, listener) &&
840             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
841                                  "offset", offset_matcher_, listener) &&
842             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2),
843                                  "length", length_matcher_, listener) &&
844             PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
845                                  effect_matcher_, listener) &&
846             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
847                                  "control", control_matcher_, listener));
848   }
849
850  private:
851   const Matcher<BufferAccess> access_matcher_;
852   const Matcher<Node*> buffer_matcher_;
853   const Matcher<Node*> offset_matcher_;
854   const Matcher<Node*> length_matcher_;
855   const Matcher<Node*> effect_matcher_;
856   const Matcher<Node*> control_matcher_;
857 };
858
859
860 class IsStoreBufferMatcher FINAL : public NodeMatcher {
861  public:
862   IsStoreBufferMatcher(const Matcher<BufferAccess>& access_matcher,
863                        const Matcher<Node*>& buffer_matcher,
864                        const Matcher<Node*>& offset_matcher,
865                        const Matcher<Node*>& length_matcher,
866                        const Matcher<Node*>& value_matcher,
867                        const Matcher<Node*>& effect_matcher,
868                        const Matcher<Node*>& control_matcher)
869       : NodeMatcher(IrOpcode::kStoreBuffer),
870         access_matcher_(access_matcher),
871         buffer_matcher_(buffer_matcher),
872         offset_matcher_(offset_matcher),
873         length_matcher_(length_matcher),
874         value_matcher_(value_matcher),
875         effect_matcher_(effect_matcher),
876         control_matcher_(control_matcher) {}
877
878   void DescribeTo(std::ostream* os) const FINAL {
879     NodeMatcher::DescribeTo(os);
880     *os << " whose access (";
881     access_matcher_.DescribeTo(os);
882     *os << "), buffer (";
883     buffer_matcher_.DescribeTo(os);
884     *os << "), offset (";
885     offset_matcher_.DescribeTo(os);
886     *os << "), length (";
887     length_matcher_.DescribeTo(os);
888     *os << "), value (";
889     value_matcher_.DescribeTo(os);
890     *os << "), effect (";
891     effect_matcher_.DescribeTo(os);
892     *os << ") and control (";
893     control_matcher_.DescribeTo(os);
894     *os << ")";
895   }
896
897   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
898     return (NodeMatcher::MatchAndExplain(node, listener) &&
899             PrintMatchAndExplain(BufferAccessOf(node->op()), "access",
900                                  access_matcher_, listener) &&
901             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
902                                  "buffer", buffer_matcher_, listener) &&
903             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
904                                  "offset", offset_matcher_, listener) &&
905             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2),
906                                  "length", length_matcher_, listener) &&
907             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 3),
908                                  "value", value_matcher_, listener) &&
909             PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
910                                  effect_matcher_, listener) &&
911             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
912                                  "control", control_matcher_, listener));
913   }
914
915  private:
916   const Matcher<BufferAccess> access_matcher_;
917   const Matcher<Node*> buffer_matcher_;
918   const Matcher<Node*> offset_matcher_;
919   const Matcher<Node*> length_matcher_;
920   const Matcher<Node*> value_matcher_;
921   const Matcher<Node*> effect_matcher_;
922   const Matcher<Node*> control_matcher_;
923 };
924
925
926 class IsLoadElementMatcher FINAL : public NodeMatcher {
927  public:
928   IsLoadElementMatcher(const Matcher<ElementAccess>& access_matcher,
929                        const Matcher<Node*>& base_matcher,
930                        const Matcher<Node*>& index_matcher,
931                        const Matcher<Node*>& effect_matcher,
932                        const Matcher<Node*>& control_matcher)
933       : NodeMatcher(IrOpcode::kLoadElement),
934         access_matcher_(access_matcher),
935         base_matcher_(base_matcher),
936         index_matcher_(index_matcher),
937         effect_matcher_(effect_matcher),
938         control_matcher_(control_matcher) {}
939
940   void DescribeTo(std::ostream* os) const FINAL {
941     NodeMatcher::DescribeTo(os);
942     *os << " whose access (";
943     access_matcher_.DescribeTo(os);
944     *os << "), base (";
945     base_matcher_.DescribeTo(os);
946     *os << "), index (";
947     index_matcher_.DescribeTo(os);
948     *os << "), effect (";
949     effect_matcher_.DescribeTo(os);
950     *os << ") and control (";
951     control_matcher_.DescribeTo(os);
952     *os << ")";
953   }
954
955   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
956     return (NodeMatcher::MatchAndExplain(node, listener) &&
957             PrintMatchAndExplain(OpParameter<ElementAccess>(node), "access",
958                                  access_matcher_, listener) &&
959             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
960                                  base_matcher_, listener) &&
961             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
962                                  "index", index_matcher_, listener) &&
963             PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
964                                  effect_matcher_, listener) &&
965             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
966                                  "control", control_matcher_, listener));
967   }
968
969  private:
970   const Matcher<ElementAccess> access_matcher_;
971   const Matcher<Node*> base_matcher_;
972   const Matcher<Node*> index_matcher_;
973   const Matcher<Node*> effect_matcher_;
974   const Matcher<Node*> control_matcher_;
975 };
976
977
978 class IsStoreElementMatcher FINAL : public NodeMatcher {
979  public:
980   IsStoreElementMatcher(const Matcher<ElementAccess>& access_matcher,
981                         const Matcher<Node*>& base_matcher,
982                         const Matcher<Node*>& index_matcher,
983                         const Matcher<Node*>& value_matcher,
984                         const Matcher<Node*>& effect_matcher,
985                         const Matcher<Node*>& control_matcher)
986       : NodeMatcher(IrOpcode::kStoreElement),
987         access_matcher_(access_matcher),
988         base_matcher_(base_matcher),
989         index_matcher_(index_matcher),
990         value_matcher_(value_matcher),
991         effect_matcher_(effect_matcher),
992         control_matcher_(control_matcher) {}
993
994   void DescribeTo(std::ostream* os) const FINAL {
995     NodeMatcher::DescribeTo(os);
996     *os << " whose access (";
997     access_matcher_.DescribeTo(os);
998     *os << "), base (";
999     base_matcher_.DescribeTo(os);
1000     *os << "), index (";
1001     index_matcher_.DescribeTo(os);
1002     *os << "), value (";
1003     value_matcher_.DescribeTo(os);
1004     *os << "), effect (";
1005     effect_matcher_.DescribeTo(os);
1006     *os << ") and control (";
1007     control_matcher_.DescribeTo(os);
1008     *os << ")";
1009   }
1010
1011   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
1012     return (NodeMatcher::MatchAndExplain(node, listener) &&
1013             PrintMatchAndExplain(OpParameter<ElementAccess>(node), "access",
1014                                  access_matcher_, listener) &&
1015             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
1016                                  base_matcher_, listener) &&
1017             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
1018                                  "index", index_matcher_, listener) &&
1019             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2),
1020                                  "value", value_matcher_, listener) &&
1021             PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
1022                                  effect_matcher_, listener) &&
1023             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
1024                                  "control", control_matcher_, listener));
1025   }
1026
1027  private:
1028   const Matcher<ElementAccess> access_matcher_;
1029   const Matcher<Node*> base_matcher_;
1030   const Matcher<Node*> index_matcher_;
1031   const Matcher<Node*> value_matcher_;
1032   const Matcher<Node*> effect_matcher_;
1033   const Matcher<Node*> control_matcher_;
1034 };
1035
1036
1037 class IsLoadMatcher FINAL : public NodeMatcher {
1038  public:
1039   IsLoadMatcher(const Matcher<LoadRepresentation>& rep_matcher,
1040                 const Matcher<Node*>& base_matcher,
1041                 const Matcher<Node*>& index_matcher,
1042                 const Matcher<Node*>& effect_matcher,
1043                 const Matcher<Node*>& control_matcher)
1044       : NodeMatcher(IrOpcode::kLoad),
1045         rep_matcher_(rep_matcher),
1046         base_matcher_(base_matcher),
1047         index_matcher_(index_matcher),
1048         effect_matcher_(effect_matcher),
1049         control_matcher_(control_matcher) {}
1050
1051   void DescribeTo(std::ostream* os) const FINAL {
1052     NodeMatcher::DescribeTo(os);
1053     *os << " whose rep (";
1054     rep_matcher_.DescribeTo(os);
1055     *os << "), base (";
1056     base_matcher_.DescribeTo(os);
1057     *os << "), index (";
1058     index_matcher_.DescribeTo(os);
1059     *os << "), effect (";
1060     effect_matcher_.DescribeTo(os);
1061     *os << ") and control (";
1062     control_matcher_.DescribeTo(os);
1063     *os << ")";
1064   }
1065
1066   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
1067     return (NodeMatcher::MatchAndExplain(node, listener) &&
1068             PrintMatchAndExplain(OpParameter<LoadRepresentation>(node), "rep",
1069                                  rep_matcher_, listener) &&
1070             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
1071                                  base_matcher_, listener) &&
1072             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
1073                                  "index", index_matcher_, listener) &&
1074             PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
1075                                  effect_matcher_, listener) &&
1076             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
1077                                  "control", control_matcher_, listener));
1078   }
1079
1080  private:
1081   const Matcher<LoadRepresentation> rep_matcher_;
1082   const Matcher<Node*> base_matcher_;
1083   const Matcher<Node*> index_matcher_;
1084   const Matcher<Node*> effect_matcher_;
1085   const Matcher<Node*> control_matcher_;
1086 };
1087
1088
1089 class IsToNumberMatcher FINAL : public NodeMatcher {
1090  public:
1091   IsToNumberMatcher(const Matcher<Node*>& base_matcher,
1092                     const Matcher<Node*>& context_matcher,
1093                     const Matcher<Node*>& effect_matcher,
1094                     const Matcher<Node*>& control_matcher)
1095       : NodeMatcher(IrOpcode::kJSToNumber),
1096         base_matcher_(base_matcher),
1097         context_matcher_(context_matcher),
1098         effect_matcher_(effect_matcher),
1099         control_matcher_(control_matcher) {}
1100
1101   void DescribeTo(std::ostream* os) const FINAL {
1102     NodeMatcher::DescribeTo(os);
1103     *os << " whose base (";
1104     base_matcher_.DescribeTo(os);
1105     *os << "), context (";
1106     context_matcher_.DescribeTo(os);
1107     *os << "), effect (";
1108     effect_matcher_.DescribeTo(os);
1109     *os << ") and control (";
1110     control_matcher_.DescribeTo(os);
1111     *os << ")";
1112   }
1113
1114   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
1115     return (NodeMatcher::MatchAndExplain(node, listener) &&
1116             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
1117                                  base_matcher_, listener) &&
1118             PrintMatchAndExplain(NodeProperties::GetContextInput(node),
1119                                  "context", context_matcher_, listener) &&
1120             PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
1121                                  effect_matcher_, listener) &&
1122             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
1123                                  "control", control_matcher_, listener));
1124   }
1125
1126  private:
1127   const Matcher<Node*> base_matcher_;
1128   const Matcher<Node*> context_matcher_;
1129   const Matcher<Node*> effect_matcher_;
1130   const Matcher<Node*> control_matcher_;
1131 };
1132
1133
1134 class IsStoreMatcher FINAL : public NodeMatcher {
1135  public:
1136   IsStoreMatcher(const Matcher<StoreRepresentation>& rep_matcher,
1137                  const Matcher<Node*>& base_matcher,
1138                  const Matcher<Node*>& index_matcher,
1139                  const Matcher<Node*>& value_matcher,
1140                  const Matcher<Node*>& effect_matcher,
1141                  const Matcher<Node*>& control_matcher)
1142       : NodeMatcher(IrOpcode::kStore),
1143         rep_matcher_(rep_matcher),
1144         base_matcher_(base_matcher),
1145         index_matcher_(index_matcher),
1146         value_matcher_(value_matcher),
1147         effect_matcher_(effect_matcher),
1148         control_matcher_(control_matcher) {}
1149
1150   void DescribeTo(std::ostream* os) const FINAL {
1151     NodeMatcher::DescribeTo(os);
1152     *os << " whose rep (";
1153     rep_matcher_.DescribeTo(os);
1154     *os << "), base (";
1155     base_matcher_.DescribeTo(os);
1156     *os << "), index (";
1157     index_matcher_.DescribeTo(os);
1158     *os << "), value (";
1159     value_matcher_.DescribeTo(os);
1160     *os << "), effect (";
1161     effect_matcher_.DescribeTo(os);
1162     *os << ") and control (";
1163     control_matcher_.DescribeTo(os);
1164     *os << ")";
1165   }
1166
1167   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
1168     return (NodeMatcher::MatchAndExplain(node, listener) &&
1169             PrintMatchAndExplain(OpParameter<StoreRepresentation>(node), "rep",
1170                                  rep_matcher_, listener) &&
1171             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
1172                                  base_matcher_, listener) &&
1173             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
1174                                  "index", index_matcher_, listener) &&
1175             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2),
1176                                  "value", value_matcher_, listener) &&
1177             PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
1178                                  effect_matcher_, listener) &&
1179             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
1180                                  "control", control_matcher_, listener));
1181   }
1182
1183  private:
1184   const Matcher<StoreRepresentation> rep_matcher_;
1185   const Matcher<Node*> base_matcher_;
1186   const Matcher<Node*> index_matcher_;
1187   const Matcher<Node*> value_matcher_;
1188   const Matcher<Node*> effect_matcher_;
1189   const Matcher<Node*> control_matcher_;
1190 };
1191
1192
1193 class IsBinopMatcher FINAL : public NodeMatcher {
1194  public:
1195   IsBinopMatcher(IrOpcode::Value opcode, const Matcher<Node*>& lhs_matcher,
1196                  const Matcher<Node*>& rhs_matcher)
1197       : NodeMatcher(opcode),
1198         lhs_matcher_(lhs_matcher),
1199         rhs_matcher_(rhs_matcher) {}
1200
1201   void DescribeTo(std::ostream* os) const FINAL {
1202     NodeMatcher::DescribeTo(os);
1203     *os << " whose lhs (";
1204     lhs_matcher_.DescribeTo(os);
1205     *os << ") and rhs (";
1206     rhs_matcher_.DescribeTo(os);
1207     *os << ")";
1208   }
1209
1210   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
1211     return (NodeMatcher::MatchAndExplain(node, listener) &&
1212             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "lhs",
1213                                  lhs_matcher_, listener) &&
1214             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "rhs",
1215                                  rhs_matcher_, listener));
1216   }
1217
1218  private:
1219   const Matcher<Node*> lhs_matcher_;
1220   const Matcher<Node*> rhs_matcher_;
1221 };
1222
1223
1224 class IsUnopMatcher FINAL : public NodeMatcher {
1225  public:
1226   IsUnopMatcher(IrOpcode::Value opcode, const Matcher<Node*>& input_matcher)
1227       : NodeMatcher(opcode), input_matcher_(input_matcher) {}
1228
1229   void DescribeTo(std::ostream* os) const FINAL {
1230     NodeMatcher::DescribeTo(os);
1231     *os << " whose input (";
1232     input_matcher_.DescribeTo(os);
1233     *os << ")";
1234   }
1235
1236   bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
1237     return (NodeMatcher::MatchAndExplain(node, listener) &&
1238             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
1239                                  "input", input_matcher_, listener));
1240   }
1241
1242  private:
1243   const Matcher<Node*> input_matcher_;
1244 };
1245
1246 }  // namespace
1247
1248
1249 Matcher<Node*> IsAlways() {
1250   return MakeMatcher(new NodeMatcher(IrOpcode::kAlways));
1251 }
1252
1253
1254 Matcher<Node*> IsEnd(const Matcher<Node*>& control_matcher) {
1255   return MakeMatcher(new IsControl1Matcher(IrOpcode::kEnd, control_matcher));
1256 }
1257
1258
1259 Matcher<Node*> IsBranch(const Matcher<Node*>& value_matcher,
1260                         const Matcher<Node*>& control_matcher) {
1261   return MakeMatcher(new IsBranchMatcher(value_matcher, control_matcher));
1262 }
1263
1264
1265 Matcher<Node*> IsMerge(const Matcher<Node*>& control0_matcher,
1266                        const Matcher<Node*>& control1_matcher) {
1267   return MakeMatcher(new IsControl2Matcher(IrOpcode::kMerge, control0_matcher,
1268                                            control1_matcher));
1269 }
1270
1271
1272 Matcher<Node*> IsMerge(const Matcher<Node*>& control0_matcher,
1273                        const Matcher<Node*>& control1_matcher,
1274                        const Matcher<Node*>& control2_matcher) {
1275   return MakeMatcher(new IsControl3Matcher(IrOpcode::kMerge, control0_matcher,
1276                                            control1_matcher, control2_matcher));
1277 }
1278
1279
1280 Matcher<Node*> IsLoop(const Matcher<Node*>& control0_matcher,
1281                       const Matcher<Node*>& control1_matcher) {
1282   return MakeMatcher(new IsControl2Matcher(IrOpcode::kLoop, control0_matcher,
1283                                            control1_matcher));
1284 }
1285
1286
1287 Matcher<Node*> IsLoop(const Matcher<Node*>& control0_matcher,
1288                       const Matcher<Node*>& control1_matcher,
1289                       const Matcher<Node*>& control2_matcher) {
1290   return MakeMatcher(new IsControl3Matcher(IrOpcode::kLoop, control0_matcher,
1291                                            control1_matcher, control2_matcher));
1292 }
1293
1294
1295 Matcher<Node*> IsIfTrue(const Matcher<Node*>& control_matcher) {
1296   return MakeMatcher(new IsControl1Matcher(IrOpcode::kIfTrue, control_matcher));
1297 }
1298
1299
1300 Matcher<Node*> IsIfFalse(const Matcher<Node*>& control_matcher) {
1301   return MakeMatcher(
1302       new IsControl1Matcher(IrOpcode::kIfFalse, control_matcher));
1303 }
1304
1305
1306 Matcher<Node*> IsSwitch(const Matcher<Node*>& value_matcher,
1307                         const Matcher<Node*>& control_matcher) {
1308   return MakeMatcher(new IsSwitchMatcher(value_matcher, control_matcher));
1309 }
1310
1311
1312 Matcher<Node*> IsIfValue(const Matcher<int32_t>& value_matcher,
1313                          const Matcher<Node*>& control_matcher) {
1314   return MakeMatcher(new IsIfValueMatcher(value_matcher, control_matcher));
1315 }
1316
1317
1318 Matcher<Node*> IsIfDefault(const Matcher<Node*>& control_matcher) {
1319   return MakeMatcher(
1320       new IsControl1Matcher(IrOpcode::kIfDefault, control_matcher));
1321 }
1322
1323
1324 Matcher<Node*> IsValueEffect(const Matcher<Node*>& value_matcher) {
1325   return MakeMatcher(new IsUnopMatcher(IrOpcode::kValueEffect, value_matcher));
1326 }
1327
1328
1329 Matcher<Node*> IsFinish(const Matcher<Node*>& value_matcher,
1330                         const Matcher<Node*>& effect_matcher) {
1331   return MakeMatcher(new IsFinishMatcher(value_matcher, effect_matcher));
1332 }
1333
1334
1335 Matcher<Node*> IsReturn(const Matcher<Node*>& value_matcher,
1336                         const Matcher<Node*>& effect_matcher,
1337                         const Matcher<Node*>& control_matcher) {
1338   return MakeMatcher(
1339       new IsReturnMatcher(value_matcher, effect_matcher, control_matcher));
1340 }
1341
1342
1343 Matcher<Node*> IsExternalConstant(
1344     const Matcher<ExternalReference>& value_matcher) {
1345   return MakeMatcher(new IsConstantMatcher<ExternalReference>(
1346       IrOpcode::kExternalConstant, value_matcher));
1347 }
1348
1349
1350 Matcher<Node*> IsHeapConstant(
1351     const Matcher<Unique<HeapObject> >& value_matcher) {
1352   return MakeMatcher(new IsConstantMatcher<Unique<HeapObject> >(
1353       IrOpcode::kHeapConstant, value_matcher));
1354 }
1355
1356
1357 Matcher<Node*> IsInt32Constant(const Matcher<int32_t>& value_matcher) {
1358   return MakeMatcher(
1359       new IsConstantMatcher<int32_t>(IrOpcode::kInt32Constant, value_matcher));
1360 }
1361
1362
1363 Matcher<Node*> IsInt64Constant(const Matcher<int64_t>& value_matcher) {
1364   return MakeMatcher(
1365       new IsConstantMatcher<int64_t>(IrOpcode::kInt64Constant, value_matcher));
1366 }
1367
1368
1369 Matcher<Node*> IsFloat32Constant(const Matcher<float>& value_matcher) {
1370   return MakeMatcher(
1371       new IsConstantMatcher<float>(IrOpcode::kFloat32Constant, value_matcher));
1372 }
1373
1374
1375 Matcher<Node*> IsFloat64Constant(const Matcher<double>& value_matcher) {
1376   return MakeMatcher(
1377       new IsConstantMatcher<double>(IrOpcode::kFloat64Constant, value_matcher));
1378 }
1379
1380
1381 Matcher<Node*> IsNumberConstant(const Matcher<double>& value_matcher) {
1382   return MakeMatcher(
1383       new IsConstantMatcher<double>(IrOpcode::kNumberConstant, value_matcher));
1384 }
1385
1386
1387 Matcher<Node*> IsSelect(const Matcher<MachineType>& type_matcher,
1388                         const Matcher<Node*>& value0_matcher,
1389                         const Matcher<Node*>& value1_matcher,
1390                         const Matcher<Node*>& value2_matcher) {
1391   return MakeMatcher(new IsSelectMatcher(type_matcher, value0_matcher,
1392                                          value1_matcher, value2_matcher));
1393 }
1394
1395
1396 Matcher<Node*> IsPhi(const Matcher<MachineType>& type_matcher,
1397                      const Matcher<Node*>& value0_matcher,
1398                      const Matcher<Node*>& value1_matcher,
1399                      const Matcher<Node*>& merge_matcher) {
1400   return MakeMatcher(new IsPhiMatcher(type_matcher, value0_matcher,
1401                                       value1_matcher, merge_matcher));
1402 }
1403
1404
1405 Matcher<Node*> IsPhi(const Matcher<MachineType>& type_matcher,
1406                      const Matcher<Node*>& value0_matcher,
1407                      const Matcher<Node*>& value1_matcher,
1408                      const Matcher<Node*>& value2_matcher,
1409                      const Matcher<Node*>& merge_matcher) {
1410   return MakeMatcher(new IsPhi2Matcher(type_matcher, value0_matcher,
1411                                        value1_matcher, value2_matcher,
1412                                        merge_matcher));
1413 }
1414
1415
1416 Matcher<Node*> IsEffectPhi(const Matcher<Node*>& effect0_matcher,
1417                            const Matcher<Node*>& effect1_matcher,
1418                            const Matcher<Node*>& merge_matcher) {
1419   return MakeMatcher(
1420       new IsEffectPhiMatcher(effect0_matcher, effect1_matcher, merge_matcher));
1421 }
1422
1423
1424 Matcher<Node*> IsEffectSet(const Matcher<Node*>& effect0_matcher,
1425                            const Matcher<Node*>& effect1_matcher) {
1426   return MakeMatcher(new IsEffectSetMatcher(effect0_matcher, effect1_matcher));
1427 }
1428
1429
1430 Matcher<Node*> IsProjection(const Matcher<size_t>& index_matcher,
1431                             const Matcher<Node*>& base_matcher) {
1432   return MakeMatcher(new IsProjectionMatcher(index_matcher, base_matcher));
1433 }
1434
1435
1436 Matcher<Node*> IsCall(const Matcher<CallDescriptor*>& descriptor_matcher,
1437                       const Matcher<Node*>& value0_matcher,
1438                       const Matcher<Node*>& value1_matcher,
1439                       const Matcher<Node*>& effect_matcher,
1440                       const Matcher<Node*>& control_matcher) {
1441   return MakeMatcher(new IsCall2Matcher(descriptor_matcher, value0_matcher,
1442                                         value1_matcher, effect_matcher,
1443                                         control_matcher));
1444 }
1445
1446
1447 Matcher<Node*> IsCall(const Matcher<CallDescriptor*>& descriptor_matcher,
1448                       const Matcher<Node*>& value0_matcher,
1449                       const Matcher<Node*>& value1_matcher,
1450                       const Matcher<Node*>& value2_matcher,
1451                       const Matcher<Node*>& value3_matcher,
1452                       const Matcher<Node*>& effect_matcher,
1453                       const Matcher<Node*>& control_matcher) {
1454   return MakeMatcher(new IsCall4Matcher(
1455       descriptor_matcher, value0_matcher, value1_matcher, value2_matcher,
1456       value3_matcher, effect_matcher, control_matcher));
1457 }
1458
1459
1460 Matcher<Node*> IsLoadField(const Matcher<FieldAccess>& access_matcher,
1461                            const Matcher<Node*>& base_matcher,
1462                            const Matcher<Node*>& effect_matcher,
1463                            const Matcher<Node*>& control_matcher) {
1464   return MakeMatcher(new IsLoadFieldMatcher(access_matcher, base_matcher,
1465                                             effect_matcher, control_matcher));
1466 }
1467
1468
1469 Matcher<Node*> IsStoreField(const Matcher<FieldAccess>& access_matcher,
1470                             const Matcher<Node*>& base_matcher,
1471                             const Matcher<Node*>& value_matcher,
1472                             const Matcher<Node*>& effect_matcher,
1473                             const Matcher<Node*>& control_matcher) {
1474   return MakeMatcher(new IsStoreFieldMatcher(access_matcher, base_matcher,
1475                                              value_matcher, effect_matcher,
1476                                              control_matcher));
1477 }
1478
1479
1480 Matcher<Node*> IsLoadBuffer(const Matcher<BufferAccess>& access_matcher,
1481                             const Matcher<Node*>& buffer_matcher,
1482                             const Matcher<Node*>& offset_matcher,
1483                             const Matcher<Node*>& length_matcher,
1484                             const Matcher<Node*>& effect_matcher,
1485                             const Matcher<Node*>& control_matcher) {
1486   return MakeMatcher(new IsLoadBufferMatcher(access_matcher, buffer_matcher,
1487                                              offset_matcher, length_matcher,
1488                                              effect_matcher, control_matcher));
1489 }
1490
1491
1492 Matcher<Node*> IsStoreBuffer(const Matcher<BufferAccess>& access_matcher,
1493                              const Matcher<Node*>& buffer_matcher,
1494                              const Matcher<Node*>& offset_matcher,
1495                              const Matcher<Node*>& length_matcher,
1496                              const Matcher<Node*>& value_matcher,
1497                              const Matcher<Node*>& effect_matcher,
1498                              const Matcher<Node*>& control_matcher) {
1499   return MakeMatcher(new IsStoreBufferMatcher(
1500       access_matcher, buffer_matcher, offset_matcher, length_matcher,
1501       value_matcher, effect_matcher, control_matcher));
1502 }
1503
1504
1505 Matcher<Node*> IsLoadElement(const Matcher<ElementAccess>& access_matcher,
1506                              const Matcher<Node*>& base_matcher,
1507                              const Matcher<Node*>& index_matcher,
1508                              const Matcher<Node*>& effect_matcher,
1509                              const Matcher<Node*>& control_matcher) {
1510   return MakeMatcher(new IsLoadElementMatcher(access_matcher, base_matcher,
1511                                               index_matcher, effect_matcher,
1512                                               control_matcher));
1513 }
1514
1515
1516 Matcher<Node*> IsStoreElement(const Matcher<ElementAccess>& access_matcher,
1517                               const Matcher<Node*>& base_matcher,
1518                               const Matcher<Node*>& index_matcher,
1519                               const Matcher<Node*>& value_matcher,
1520                               const Matcher<Node*>& effect_matcher,
1521                               const Matcher<Node*>& control_matcher) {
1522   return MakeMatcher(new IsStoreElementMatcher(
1523       access_matcher, base_matcher, index_matcher, value_matcher,
1524       effect_matcher, control_matcher));
1525 }
1526
1527
1528 Matcher<Node*> IsLoad(const Matcher<LoadRepresentation>& rep_matcher,
1529                       const Matcher<Node*>& base_matcher,
1530                       const Matcher<Node*>& index_matcher,
1531                       const Matcher<Node*>& effect_matcher,
1532                       const Matcher<Node*>& control_matcher) {
1533   return MakeMatcher(new IsLoadMatcher(rep_matcher, base_matcher, index_matcher,
1534                                        effect_matcher, control_matcher));
1535 }
1536
1537
1538 Matcher<Node*> IsToNumber(const Matcher<Node*>& base_matcher,
1539                           const Matcher<Node*>& context_matcher,
1540                           const Matcher<Node*>& effect_matcher,
1541                           const Matcher<Node*>& control_matcher) {
1542   return MakeMatcher(new IsToNumberMatcher(base_matcher, context_matcher,
1543                                            effect_matcher, control_matcher));
1544 }
1545
1546
1547 Matcher<Node*> IsStore(const Matcher<StoreRepresentation>& rep_matcher,
1548                        const Matcher<Node*>& base_matcher,
1549                        const Matcher<Node*>& index_matcher,
1550                        const Matcher<Node*>& value_matcher,
1551                        const Matcher<Node*>& effect_matcher,
1552                        const Matcher<Node*>& control_matcher) {
1553   return MakeMatcher(new IsStoreMatcher(rep_matcher, base_matcher,
1554                                         index_matcher, value_matcher,
1555                                         effect_matcher, control_matcher));
1556 }
1557
1558
1559 #define IS_BINOP_MATCHER(Name)                                            \
1560   Matcher<Node*> Is##Name(const Matcher<Node*>& lhs_matcher,              \
1561                           const Matcher<Node*>& rhs_matcher) {            \
1562     return MakeMatcher(                                                   \
1563         new IsBinopMatcher(IrOpcode::k##Name, lhs_matcher, rhs_matcher)); \
1564   }
1565 IS_BINOP_MATCHER(NumberEqual)
1566 IS_BINOP_MATCHER(NumberLessThan)
1567 IS_BINOP_MATCHER(NumberSubtract)
1568 IS_BINOP_MATCHER(NumberMultiply)
1569 IS_BINOP_MATCHER(Word32And)
1570 IS_BINOP_MATCHER(Word32Sar)
1571 IS_BINOP_MATCHER(Word32Shl)
1572 IS_BINOP_MATCHER(Word32Shr)
1573 IS_BINOP_MATCHER(Word32Ror)
1574 IS_BINOP_MATCHER(Word32Equal)
1575 IS_BINOP_MATCHER(Word64And)
1576 IS_BINOP_MATCHER(Word64Sar)
1577 IS_BINOP_MATCHER(Word64Shl)
1578 IS_BINOP_MATCHER(Word64Equal)
1579 IS_BINOP_MATCHER(Int32AddWithOverflow)
1580 IS_BINOP_MATCHER(Int32Add)
1581 IS_BINOP_MATCHER(Int32Sub)
1582 IS_BINOP_MATCHER(Int32Mul)
1583 IS_BINOP_MATCHER(Int32MulHigh)
1584 IS_BINOP_MATCHER(Int32LessThan)
1585 IS_BINOP_MATCHER(Uint32LessThan)
1586 IS_BINOP_MATCHER(Uint32LessThanOrEqual)
1587 IS_BINOP_MATCHER(Float64Sub)
1588 #undef IS_BINOP_MATCHER
1589
1590
1591 #define IS_UNOP_MATCHER(Name)                                                \
1592   Matcher<Node*> Is##Name(const Matcher<Node*>& input_matcher) {             \
1593     return MakeMatcher(new IsUnopMatcher(IrOpcode::k##Name, input_matcher)); \
1594   }
1595 IS_UNOP_MATCHER(AnyToBoolean)
1596 IS_UNOP_MATCHER(BooleanNot)
1597 IS_UNOP_MATCHER(ChangeFloat64ToInt32)
1598 IS_UNOP_MATCHER(ChangeFloat64ToUint32)
1599 IS_UNOP_MATCHER(ChangeInt32ToFloat64)
1600 IS_UNOP_MATCHER(ChangeInt32ToInt64)
1601 IS_UNOP_MATCHER(ChangeUint32ToFloat64)
1602 IS_UNOP_MATCHER(ChangeUint32ToUint64)
1603 IS_UNOP_MATCHER(TruncateFloat64ToFloat32)
1604 IS_UNOP_MATCHER(TruncateFloat64ToInt32)
1605 IS_UNOP_MATCHER(TruncateInt64ToInt32)
1606 IS_UNOP_MATCHER(Float64Sqrt)
1607 IS_UNOP_MATCHER(Float64Floor)
1608 IS_UNOP_MATCHER(Float64Ceil)
1609 IS_UNOP_MATCHER(Float64RoundTruncate)
1610 IS_UNOP_MATCHER(Float64RoundTiesAway)
1611 IS_UNOP_MATCHER(NumberToInt32)
1612 IS_UNOP_MATCHER(NumberToUint32)
1613 IS_UNOP_MATCHER(ObjectIsSmi)
1614 IS_UNOP_MATCHER(ObjectIsNonNegativeSmi)
1615 #undef IS_UNOP_MATCHER
1616
1617 }  // namespace compiler
1618 }  // namespace internal
1619 }  // namespace v8