1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "test/unittests/compiler/node-test-utils.h"
6 
7 #include <vector>
8 
9 #include "src/compiler/common-operator.h"
10 #include "src/compiler/js-operator.h"
11 #include "src/compiler/node-properties.h"
12 #include "src/compiler/simplified-operator.h"
13 #include "src/handles/handles-inl.h"
14 #include "src/objects/objects-inl.h"
15 #include "src/objects/objects.h"
16 
17 using testing::_;
18 using testing::MakeMatcher;
19 using testing::MatcherInterface;
20 using testing::MatchResultListener;
21 using testing::StringMatchResultListener;
22 
23 namespace v8 {
24 namespace internal {
25 
operator ==(Handle<HeapObject> const & lhs,Handle<HeapObject> const & rhs)26 bool operator==(Handle<HeapObject> const& lhs, Handle<HeapObject> const& rhs) {
27   return lhs.is_identical_to(rhs);
28 }
29 
30 namespace compiler {
31 
32 namespace {
33 
34 template <typename T>
PrintMatchAndExplain(const T & value,const std::string & value_name,const Matcher<T> & value_matcher,MatchResultListener * listener)35 bool PrintMatchAndExplain(const T& value, const std::string& value_name,
36                           const Matcher<T>& value_matcher,
37                           MatchResultListener* listener) {
38   StringMatchResultListener value_listener;
39   if (!value_matcher.MatchAndExplain(value, &value_listener)) {
40     *listener << "whose " << value_name << " " << value << " doesn't match";
41     if (value_listener.str() != "") {
42       *listener << ", " << value_listener.str();
43     }
44     return false;
45   }
46   return true;
47 }
48 
49 class TestNodeMatcher : public MatcherInterface<Node*> {
50  public:
TestNodeMatcher(IrOpcode::Value opcode)51   explicit TestNodeMatcher(IrOpcode::Value opcode) : opcode_(opcode) {}
52 
DescribeTo(std::ostream * os) const53   void DescribeTo(std::ostream* os) const override {
54     *os << "is a " << IrOpcode::Mnemonic(opcode_) << " node";
55   }
56 
MatchAndExplain(Node * node,MatchResultListener * listener) const57   bool MatchAndExplain(Node* node,
58                        MatchResultListener* listener) const override {
59     if (node == nullptr) {
60       *listener << "which is NULL";
61       return false;
62     }
63     if (node->opcode() != opcode_) {
64       *listener << "whose opcode is " << IrOpcode::Mnemonic(node->opcode())
65                 << " but should have been " << IrOpcode::Mnemonic(opcode_);
66       return false;
67     }
68     return true;
69   }
70 
71  private:
72   const IrOpcode::Value opcode_;
73 };
74 
75 class IsBranchMatcher final : public TestNodeMatcher {
76  public:
IsBranchMatcher(const Matcher<Node * > & value_matcher,const Matcher<Node * > & control_matcher)77   IsBranchMatcher(const Matcher<Node*>& value_matcher,
78                   const Matcher<Node*>& control_matcher)
79       : TestNodeMatcher(IrOpcode::kBranch),
80         value_matcher_(value_matcher),
81         control_matcher_(control_matcher) {}
82 
DescribeTo(std::ostream * os) const83   void DescribeTo(std::ostream* os) const final {
84     TestNodeMatcher::DescribeTo(os);
85     *os << " whose value (";
86     value_matcher_.DescribeTo(os);
87     *os << ") and control (";
88     control_matcher_.DescribeTo(os);
89     *os << ")";
90   }
91 
MatchAndExplain(Node * node,MatchResultListener * listener) const92   bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
93     return (TestNodeMatcher::MatchAndExplain(node, listener) &&
94             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
95                                  "value", value_matcher_, listener) &&
96             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
97                                  "control", control_matcher_, listener));
98   }
99 
100  private:
101   const Matcher<Node*> value_matcher_;
102   const Matcher<Node*> control_matcher_;
103 };
104 
105 class IsLoopExitValueMatcher final : public TestNodeMatcher {
106  public:
IsLoopExitValueMatcher(const Matcher<MachineRepresentation> & rep_matcher,const Matcher<Node * > & value_matcher)107   IsLoopExitValueMatcher(const Matcher<MachineRepresentation>& rep_matcher,
108                          const Matcher<Node*>& value_matcher)
109       : TestNodeMatcher(IrOpcode::kLoopExitValue),
110         rep_matcher_(rep_matcher),
111         value_matcher_(value_matcher) {}
112 
DescribeTo(std::ostream * os) const113   void DescribeTo(std::ostream* os) const final {
114     TestNodeMatcher::DescribeTo(os);
115     *os << ") whose rep (";
116     rep_matcher_.DescribeTo(os);
117     *os << " and value (";
118     value_matcher_.DescribeTo(os);
119     *os << ")";
120   }
121 
MatchAndExplain(Node * node,MatchResultListener * listener) const122   bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
123     return (TestNodeMatcher::MatchAndExplain(node, listener) &&
124             PrintMatchAndExplain(LoopExitValueRepresentationOf(node->op()),
125                                  "representation", rep_matcher_, listener)) &&
126            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "value",
127                                 value_matcher_, listener);
128   }
129 
130  private:
131   const Matcher<MachineRepresentation> rep_matcher_;
132   const Matcher<Node*> value_matcher_;
133 };
134 
135 class IsSwitchMatcher final : public TestNodeMatcher {
136  public:
IsSwitchMatcher(const Matcher<Node * > & value_matcher,const Matcher<Node * > & control_matcher)137   IsSwitchMatcher(const Matcher<Node*>& value_matcher,
138                   const Matcher<Node*>& control_matcher)
139       : TestNodeMatcher(IrOpcode::kSwitch),
140         value_matcher_(value_matcher),
141         control_matcher_(control_matcher) {}
142 
DescribeTo(std::ostream * os) const143   void DescribeTo(std::ostream* os) const final {
144     TestNodeMatcher::DescribeTo(os);
145     *os << " whose value (";
146     value_matcher_.DescribeTo(os);
147     *os << ") and control (";
148     control_matcher_.DescribeTo(os);
149     *os << ")";
150   }
151 
MatchAndExplain(Node * node,MatchResultListener * listener) const152   bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
153     return (TestNodeMatcher::MatchAndExplain(node, listener) &&
154             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
155                                  "value", value_matcher_, listener) &&
156             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
157                                  "control", control_matcher_, listener));
158   }
159 
160  private:
161   const Matcher<Node*> value_matcher_;
162   const Matcher<Node*> control_matcher_;
163 };
164 
165 class IsIfValueMatcher final : public TestNodeMatcher {
166  public:
IsIfValueMatcher(const Matcher<IfValueParameters> & value_matcher,const Matcher<Node * > & control_matcher)167   IsIfValueMatcher(const Matcher<IfValueParameters>& value_matcher,
168                    const Matcher<Node*>& control_matcher)
169       : TestNodeMatcher(IrOpcode::kIfValue),
170         value_matcher_(value_matcher),
171         control_matcher_(control_matcher) {}
172 
DescribeTo(std::ostream * os) const173   void DescribeTo(std::ostream* os) const final {
174     TestNodeMatcher::DescribeTo(os);
175     *os << " whose value (";
176     value_matcher_.DescribeTo(os);
177     *os << ") and control (";
178     control_matcher_.DescribeTo(os);
179     *os << ")";
180   }
181 
MatchAndExplain(Node * node,MatchResultListener * listener) const182   bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
183     return (TestNodeMatcher::MatchAndExplain(node, listener) &&
184             PrintMatchAndExplain(IfValueParametersOf(node->op()), "value",
185                                  value_matcher_, listener) &&
186             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
187                                  "control", control_matcher_, listener));
188   }
189 
190  private:
191   const Matcher<IfValueParameters> value_matcher_;
192   const Matcher<Node*> control_matcher_;
193 };
194 
195 class IsControl1Matcher final : public TestNodeMatcher {
196  public:
IsControl1Matcher(IrOpcode::Value opcode,const Matcher<Node * > & control_matcher)197   IsControl1Matcher(IrOpcode::Value opcode,
198                     const Matcher<Node*>& control_matcher)
199       : TestNodeMatcher(opcode), control_matcher_(control_matcher) {}
200 
DescribeTo(std::ostream * os) const201   void DescribeTo(std::ostream* os) const final {
202     TestNodeMatcher::DescribeTo(os);
203     *os << " whose control (";
204     control_matcher_.DescribeTo(os);
205     *os << ")";
206   }
207 
MatchAndExplain(Node * node,MatchResultListener * listener) const208   bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
209     return (TestNodeMatcher::MatchAndExplain(node, listener) &&
210             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
211                                  "control", control_matcher_, listener));
212   }
213 
214  private:
215   const Matcher<Node*> control_matcher_;
216 };
217 
218 class IsControl2Matcher final : public TestNodeMatcher {
219  public:
IsControl2Matcher(IrOpcode::Value opcode,const Matcher<Node * > & control0_matcher,const Matcher<Node * > & control1_matcher)220   IsControl2Matcher(IrOpcode::Value opcode,
221                     const Matcher<Node*>& control0_matcher,
222                     const Matcher<Node*>& control1_matcher)
223       : TestNodeMatcher(opcode),
224         control0_matcher_(control0_matcher),
225         control1_matcher_(control1_matcher) {}
226 
DescribeTo(std::ostream * os) const227   void DescribeTo(std::ostream* os) const final {
228     TestNodeMatcher::DescribeTo(os);
229     *os << " whose control0 (";
230     control0_matcher_.DescribeTo(os);
231     *os << ") and control1 (";
232     control1_matcher_.DescribeTo(os);
233     *os << ")";
234   }
235 
MatchAndExplain(Node * node,MatchResultListener * listener) const236   bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
237     return (TestNodeMatcher::MatchAndExplain(node, listener) &&
238             PrintMatchAndExplain(NodeProperties::GetControlInput(node, 0),
239                                  "control0", control0_matcher_, listener) &&
240             PrintMatchAndExplain(NodeProperties::GetControlInput(node, 1),
241                                  "control1", control1_matcher_, listener));
242   }
243 
244  private:
245   const Matcher<Node*> control0_matcher_;
246   const Matcher<Node*> control1_matcher_;
247 };
248 
249 class IsControl3Matcher final : public TestNodeMatcher {
250  public:
IsControl3Matcher(IrOpcode::Value opcode,const Matcher<Node * > & control0_matcher,const Matcher<Node * > & control1_matcher,const Matcher<Node * > & control2_matcher)251   IsControl3Matcher(IrOpcode::Value opcode,
252                     const Matcher<Node*>& control0_matcher,
253                     const Matcher<Node*>& control1_matcher,
254                     const Matcher<Node*>& control2_matcher)
255       : TestNodeMatcher(opcode),
256         control0_matcher_(control0_matcher),
257         control1_matcher_(control1_matcher),
258         control2_matcher_(control2_matcher) {}
259 
DescribeTo(std::ostream * os) const260   void DescribeTo(std::ostream* os) const final {
261     TestNodeMatcher::DescribeTo(os);
262     *os << " whose control0 (";
263     control0_matcher_.DescribeTo(os);
264     *os << ") and control1 (";
265     control1_matcher_.DescribeTo(os);
266     *os << ") and control2 (";
267     control2_matcher_.DescribeTo(os);
268     *os << ")";
269   }
270 
MatchAndExplain(Node * node,MatchResultListener * listener) const271   bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
272     return (TestNodeMatcher::MatchAndExplain(node, listener) &&
273             PrintMatchAndExplain(NodeProperties::GetControlInput(node, 0),
274                                  "control0", control0_matcher_, listener) &&
275             PrintMatchAndExplain(NodeProperties::GetControlInput(node, 1),
276                                  "control1", control1_matcher_, listener) &&
277             PrintMatchAndExplain(NodeProperties::GetControlInput(node, 2),
278                                  "control2", control2_matcher_, listener));
279   }
280 
281  private:
282   const Matcher<Node*> control0_matcher_;
283   const Matcher<Node*> control1_matcher_;
284   const Matcher<Node*> control2_matcher_;
285 };
286 
287 class IsBeginRegionMatcher final : public TestNodeMatcher {
288  public:
IsBeginRegionMatcher(const Matcher<Node * > & effect_matcher)289   explicit IsBeginRegionMatcher(const Matcher<Node*>& effect_matcher)
290       : TestNodeMatcher(IrOpcode::kBeginRegion),
291         effect_matcher_(effect_matcher) {}
292 
DescribeTo(std::ostream * os) const293   void DescribeTo(std::ostream* os) const final {
294     TestNodeMatcher::DescribeTo(os);
295     *os << " whose effect (";
296     effect_matcher_.DescribeTo(os);
297     *os << ")";
298   }
299 
MatchAndExplain(Node * node,MatchResultListener * listener) const300   bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
301     return (TestNodeMatcher::MatchAndExplain(node, listener) &&
302             PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
303                                  effect_matcher_, listener));
304   }
305 
306  private:
307   const Matcher<Node*> effect_matcher_;
308 };
309 
310 class IsFinishRegionMatcher final : public TestNodeMatcher {
311  public:
IsFinishRegionMatcher(const Matcher<Node * > & value_matcher,const Matcher<Node * > & effect_matcher)312   IsFinishRegionMatcher(const Matcher<Node*>& value_matcher,
313                         const Matcher<Node*>& effect_matcher)
314       : TestNodeMatcher(IrOpcode::kFinishRegion),
315         value_matcher_(value_matcher),
316         effect_matcher_(effect_matcher) {}
317 
DescribeTo(std::ostream * os) const318   void DescribeTo(std::ostream* os) const final {
319     TestNodeMatcher::DescribeTo(os);
320     *os << " whose value (";
321     value_matcher_.DescribeTo(os);
322     *os << ") and effect (";
323     effect_matcher_.DescribeTo(os);
324     *os << ")";
325   }
326 
MatchAndExplain(Node * node,MatchResultListener * listener) const327   bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
328     return (TestNodeMatcher::MatchAndExplain(node, listener) &&
329             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
330                                  "value", value_matcher_, listener) &&
331             PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
332                                  effect_matcher_, listener));
333   }
334 
335  private:
336   const Matcher<Node*> value_matcher_;
337   const Matcher<Node*> effect_matcher_;
338 };
339 
340 class IsReturnMatcher final : public TestNodeMatcher {
341  public:
IsReturnMatcher(const Matcher<Node * > & value_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)342   IsReturnMatcher(const Matcher<Node*>& value_matcher,
343                   const Matcher<Node*>& effect_matcher,
344                   const Matcher<Node*>& control_matcher)
345       : TestNodeMatcher(IrOpcode::kReturn),
346         value_matcher_(value_matcher),
347         value2_matcher_(_),
348         effect_matcher_(effect_matcher),
349         control_matcher_(control_matcher),
350         has_second_return_value_(false) {}
351 
IsReturnMatcher(const Matcher<Node * > & value_matcher,const Matcher<Node * > & value2_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)352   IsReturnMatcher(const Matcher<Node*>& value_matcher,
353                   const Matcher<Node*>& value2_matcher,
354                   const Matcher<Node*>& effect_matcher,
355                   const Matcher<Node*>& control_matcher)
356       : TestNodeMatcher(IrOpcode::kReturn),
357         value_matcher_(value_matcher),
358         value2_matcher_(value2_matcher),
359         effect_matcher_(effect_matcher),
360         control_matcher_(control_matcher),
361         has_second_return_value_(true) {}
362 
DescribeTo(std::ostream * os) const363   void DescribeTo(std::ostream* os) const final {
364     TestNodeMatcher::DescribeTo(os);
365     *os << " whose value (";
366     value_matcher_.DescribeTo(os);
367     if (has_second_return_value_) {
368       *os << ") and second value (";
369       value2_matcher_.DescribeTo(os);
370     }
371     *os << ") and effect (";
372     effect_matcher_.DescribeTo(os);
373     *os << ") and control (";
374     control_matcher_.DescribeTo(os);
375     *os << ")";
376   }
377 
MatchAndExplain(Node * node,MatchResultListener * listener) const378   bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
379     return (TestNodeMatcher::MatchAndExplain(node, listener) &&
380             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
381                                  "value", value_matcher_, listener) &&
382             (!has_second_return_value_ ||
383              PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2),
384                                   "value2", value2_matcher_, listener)) &&
385             PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
386                                  effect_matcher_, listener) &&
387             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
388                                  "control", control_matcher_, listener));
389   }
390 
391  private:
392   const Matcher<Node*> value_matcher_;
393   const Matcher<Node*> value2_matcher_;
394   const Matcher<Node*> effect_matcher_;
395   const Matcher<Node*> control_matcher_;
396   bool has_second_return_value_;
397 };
398 
399 class IsTerminateMatcher final : public TestNodeMatcher {
400  public:
IsTerminateMatcher(const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)401   IsTerminateMatcher(const Matcher<Node*>& effect_matcher,
402                      const Matcher<Node*>& control_matcher)
403       : TestNodeMatcher(IrOpcode::kTerminate),
404         effect_matcher_(effect_matcher),
405         control_matcher_(control_matcher) {}
406 
DescribeTo(std::ostream * os) const407   void DescribeTo(std::ostream* os) const final {
408     TestNodeMatcher::DescribeTo(os);
409     *os << " whose effect (";
410     effect_matcher_.DescribeTo(os);
411     *os << ") and control (";
412     control_matcher_.DescribeTo(os);
413     *os << ")";
414   }
415 
MatchAndExplain(Node * node,MatchResultListener * listener) const416   bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
417     return (TestNodeMatcher::MatchAndExplain(node, listener) &&
418             PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
419                                  effect_matcher_, listener) &&
420             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
421                                  "control", control_matcher_, listener));
422   }
423 
424  private:
425   const Matcher<Node*> effect_matcher_;
426   const Matcher<Node*> control_matcher_;
427 };
428 
429 class IsTypeGuardMatcher final : public TestNodeMatcher {
430  public:
IsTypeGuardMatcher(const Matcher<Node * > & value_matcher,const Matcher<Node * > & control_matcher)431   IsTypeGuardMatcher(const Matcher<Node*>& value_matcher,
432                      const Matcher<Node*>& control_matcher)
433       : TestNodeMatcher(IrOpcode::kTypeGuard),
434         value_matcher_(value_matcher),
435         control_matcher_(control_matcher) {}
436 
DescribeTo(std::ostream * os) const437   void DescribeTo(std::ostream* os) const final {
438     TestNodeMatcher::DescribeTo(os);
439     *os << " whose value (";
440     value_matcher_.DescribeTo(os);
441     *os << ") and control (";
442     control_matcher_.DescribeTo(os);
443     *os << ")";
444   }
445 
MatchAndExplain(Node * node,MatchResultListener * listener) const446   bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
447     return (TestNodeMatcher::MatchAndExplain(node, listener) &&
448             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
449                                  "value", value_matcher_, listener) &&
450             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
451                                  "control", control_matcher_, listener));
452   }
453 
454  private:
455   const Matcher<Node*> value_matcher_;
456   const Matcher<Node*> control_matcher_;
457 };
458 
459 template <typename T>
460 class IsConstantMatcher final : public TestNodeMatcher {
461  public:
IsConstantMatcher(IrOpcode::Value opcode,const Matcher<T> & value_matcher)462   IsConstantMatcher(IrOpcode::Value opcode, const Matcher<T>& value_matcher)
463       : TestNodeMatcher(opcode), value_matcher_(value_matcher) {}
464 
DescribeTo(std::ostream * os) const465   void DescribeTo(std::ostream* os) const final {
466     TestNodeMatcher::DescribeTo(os);
467     *os << " whose value (";
468     value_matcher_.DescribeTo(os);
469     *os << ")";
470   }
471 
MatchAndExplain(Node * node,MatchResultListener * listener) const472   bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
473     return (TestNodeMatcher::MatchAndExplain(node, listener) &&
474             PrintMatchAndExplain(OpParameter<T>(node->op()), "value",
475                                  value_matcher_, listener));
476   }
477 
478  private:
479   const Matcher<T> value_matcher_;
480 };
481 
482 class IsSelectMatcher final : public TestNodeMatcher {
483  public:
IsSelectMatcher(const Matcher<MachineRepresentation> & type_matcher,const Matcher<Node * > & value0_matcher,const Matcher<Node * > & value1_matcher,const Matcher<Node * > & value2_matcher)484   IsSelectMatcher(const Matcher<MachineRepresentation>& type_matcher,
485                   const Matcher<Node*>& value0_matcher,
486                   const Matcher<Node*>& value1_matcher,
487                   const Matcher<Node*>& value2_matcher)
488       : TestNodeMatcher(IrOpcode::kSelect),
489         type_matcher_(type_matcher),
490         value0_matcher_(value0_matcher),
491         value1_matcher_(value1_matcher),
492         value2_matcher_(value2_matcher) {}
493 
DescribeTo(std::ostream * os) const494   void DescribeTo(std::ostream* os) const final {
495     TestNodeMatcher::DescribeTo(os);
496     *os << " whose representation (";
497     type_matcher_.DescribeTo(os);
498     *os << "), value0 (";
499     value0_matcher_.DescribeTo(os);
500     *os << "), value1 (";
501     value1_matcher_.DescribeTo(os);
502     *os << ") and value2 (";
503     value2_matcher_.DescribeTo(os);
504     *os << ")";
505   }
506 
MatchAndExplain(Node * node,MatchResultListener * listener) const507   bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
508     return (
509         TestNodeMatcher::MatchAndExplain(node, listener) &&
510         PrintMatchAndExplain(SelectParametersOf(node->op()).representation(),
511                              "representation", type_matcher_, listener) &&
512         PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "value0",
513                              value0_matcher_, listener) &&
514         PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "value1",
515                              value1_matcher_, listener) &&
516         PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2), "value2",
517                              value2_matcher_, listener));
518   }
519 
520  private:
521   const Matcher<MachineRepresentation> type_matcher_;
522   const Matcher<Node*> value0_matcher_;
523   const Matcher<Node*> value1_matcher_;
524   const Matcher<Node*> value2_matcher_;
525 };
526 
527 class IsPhiMatcher final : public TestNodeMatcher {
528  public:
IsPhiMatcher(const Matcher<MachineRepresentation> & type_matcher,const Matcher<Node * > & value0_matcher,const Matcher<Node * > & value1_matcher,const Matcher<Node * > & control_matcher)529   IsPhiMatcher(const Matcher<MachineRepresentation>& type_matcher,
530                const Matcher<Node*>& value0_matcher,
531                const Matcher<Node*>& value1_matcher,
532                const Matcher<Node*>& control_matcher)
533       : TestNodeMatcher(IrOpcode::kPhi),
534         type_matcher_(type_matcher),
535         value0_matcher_(value0_matcher),
536         value1_matcher_(value1_matcher),
537         control_matcher_(control_matcher) {}
538 
DescribeTo(std::ostream * os) const539   void DescribeTo(std::ostream* os) const final {
540     TestNodeMatcher::DescribeTo(os);
541     *os << " whose representation (";
542     type_matcher_.DescribeTo(os);
543     *os << "), value0 (";
544     value0_matcher_.DescribeTo(os);
545     *os << "), value1 (";
546     value1_matcher_.DescribeTo(os);
547     *os << ") and control (";
548     control_matcher_.DescribeTo(os);
549     *os << ")";
550   }
551 
MatchAndExplain(Node * node,MatchResultListener * listener) const552   bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
553     return (TestNodeMatcher::MatchAndExplain(node, listener) &&
554             PrintMatchAndExplain(PhiRepresentationOf(node->op()),
555                                  "representation", type_matcher_, listener) &&
556             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
557                                  "value0", value0_matcher_, listener) &&
558             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
559                                  "value1", value1_matcher_, listener) &&
560             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
561                                  "control", control_matcher_, listener));
562   }
563 
564  private:
565   const Matcher<MachineRepresentation> type_matcher_;
566   const Matcher<Node*> value0_matcher_;
567   const Matcher<Node*> value1_matcher_;
568   const Matcher<Node*> control_matcher_;
569 };
570 
571 class IsPhi2Matcher final : public TestNodeMatcher {
572  public:
IsPhi2Matcher(const Matcher<MachineRepresentation> & type_matcher,const Matcher<Node * > & value0_matcher,const Matcher<Node * > & value1_matcher,const Matcher<Node * > & value2_matcher,const Matcher<Node * > & control_matcher)573   IsPhi2Matcher(const Matcher<MachineRepresentation>& type_matcher,
574                 const Matcher<Node*>& value0_matcher,
575                 const Matcher<Node*>& value1_matcher,
576                 const Matcher<Node*>& value2_matcher,
577                 const Matcher<Node*>& control_matcher)
578       : TestNodeMatcher(IrOpcode::kPhi),
579         type_matcher_(type_matcher),
580         value0_matcher_(value0_matcher),
581         value1_matcher_(value1_matcher),
582         value2_matcher_(value2_matcher),
583         control_matcher_(control_matcher) {}
584 
DescribeTo(std::ostream * os) const585   void DescribeTo(std::ostream* os) const final {
586     TestNodeMatcher::DescribeTo(os);
587     *os << " whose representation (";
588     type_matcher_.DescribeTo(os);
589     *os << "), value0 (";
590     value0_matcher_.DescribeTo(os);
591     *os << "), value1 (";
592     value1_matcher_.DescribeTo(os);
593     *os << "), value2 (";
594     value2_matcher_.DescribeTo(os);
595     *os << ") and control (";
596     control_matcher_.DescribeTo(os);
597     *os << ")";
598   }
599 
MatchAndExplain(Node * node,MatchResultListener * listener) const600   bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
601     return (TestNodeMatcher::MatchAndExplain(node, listener) &&
602             PrintMatchAndExplain(PhiRepresentationOf(node->op()),
603                                  "representation", type_matcher_, listener) &&
604             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
605                                  "value0", value0_matcher_, listener) &&
606             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
607                                  "value1", value1_matcher_, listener) &&
608             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2),
609                                  "value2", value2_matcher_, listener) &&
610             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
611                                  "control", control_matcher_, listener));
612   }
613 
614  private:
615   const Matcher<MachineRepresentation> type_matcher_;
616   const Matcher<Node*> value0_matcher_;
617   const Matcher<Node*> value1_matcher_;
618   const Matcher<Node*> value2_matcher_;
619   const Matcher<Node*> control_matcher_;
620 };
621 
622 class IsEffectPhiMatcher final : public TestNodeMatcher {
623  public:
IsEffectPhiMatcher(const Matcher<Node * > & effect0_matcher,const Matcher<Node * > & effect1_matcher,const Matcher<Node * > & control_matcher)624   IsEffectPhiMatcher(const Matcher<Node*>& effect0_matcher,
625                      const Matcher<Node*>& effect1_matcher,
626                      const Matcher<Node*>& control_matcher)
627       : TestNodeMatcher(IrOpcode::kEffectPhi),
628         effect0_matcher_(effect0_matcher),
629         effect1_matcher_(effect1_matcher),
630         control_matcher_(control_matcher) {}
631 
DescribeTo(std::ostream * os) const632   void DescribeTo(std::ostream* os) const final {
633     TestNodeMatcher::DescribeTo(os);
634     *os << "), effect0 (";
635     effect0_matcher_.DescribeTo(os);
636     *os << "), effect1 (";
637     effect1_matcher_.DescribeTo(os);
638     *os << ") and control (";
639     control_matcher_.DescribeTo(os);
640     *os << ")";
641   }
642 
MatchAndExplain(Node * node,MatchResultListener * listener) const643   bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
644     return (TestNodeMatcher::MatchAndExplain(node, listener) &&
645             PrintMatchAndExplain(NodeProperties::GetEffectInput(node, 0),
646                                  "effect0", effect0_matcher_, listener) &&
647             PrintMatchAndExplain(NodeProperties::GetEffectInput(node, 1),
648                                  "effect1", effect1_matcher_, listener) &&
649             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
650                                  "control", control_matcher_, listener));
651   }
652 
653  private:
654   const Matcher<Node*> effect0_matcher_;
655   const Matcher<Node*> effect1_matcher_;
656   const Matcher<Node*> control_matcher_;
657 };
658 
659 class IsProjectionMatcher final : public TestNodeMatcher {
660  public:
IsProjectionMatcher(const Matcher<size_t> & index_matcher,const Matcher<Node * > & base_matcher)661   IsProjectionMatcher(const Matcher<size_t>& index_matcher,
662                       const Matcher<Node*>& base_matcher)
663       : TestNodeMatcher(IrOpcode::kProjection),
664         index_matcher_(index_matcher),
665         base_matcher_(base_matcher) {}
666 
DescribeTo(std::ostream * os) const667   void DescribeTo(std::ostream* os) const final {
668     TestNodeMatcher::DescribeTo(os);
669     *os << " whose index (";
670     index_matcher_.DescribeTo(os);
671     *os << ") and base (";
672     base_matcher_.DescribeTo(os);
673     *os << ")";
674   }
675 
MatchAndExplain(Node * node,MatchResultListener * listener) const676   bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
677     return (TestNodeMatcher::MatchAndExplain(node, listener) &&
678             PrintMatchAndExplain(OpParameter<size_t>(node->op()), "index",
679                                  index_matcher_, listener) &&
680             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
681                                  base_matcher_, listener));
682   }
683 
684  private:
685   const Matcher<size_t> index_matcher_;
686   const Matcher<Node*> base_matcher_;
687 };
688 
689 class IsCallMatcher final : public TestNodeMatcher {
690  public:
IsCallMatcher(const Matcher<const CallDescriptor * > & descriptor_matcher,const std::vector<Matcher<Node * >> & value_matchers,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)691   IsCallMatcher(const Matcher<const CallDescriptor*>& descriptor_matcher,
692                 const std::vector<Matcher<Node*>>& value_matchers,
693                 const Matcher<Node*>& effect_matcher,
694                 const Matcher<Node*>& control_matcher)
695       : TestNodeMatcher(IrOpcode::kCall),
696         descriptor_matcher_(descriptor_matcher),
697         value_matchers_(value_matchers),
698         effect_matcher_(effect_matcher),
699         control_matcher_(control_matcher) {}
700 
DescribeTo(std::ostream * os) const701   void DescribeTo(std::ostream* os) const final {
702     TestNodeMatcher::DescribeTo(os);
703     for (size_t i = 0; i < value_matchers_.size(); ++i) {
704       if (i == 0) {
705         *os << " whose value0 (";
706       } else {
707         *os << "), value" << i << " (";
708       }
709       value_matchers_[i].DescribeTo(os);
710     }
711     *os << "), effect (";
712     effect_matcher_.DescribeTo(os);
713     *os << ") and control (";
714     control_matcher_.DescribeTo(os);
715     *os << ")";
716   }
717 
MatchAndExplain(Node * node,MatchResultListener * listener) const718   bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
719     if (!TestNodeMatcher::MatchAndExplain(node, listener) ||
720         !PrintMatchAndExplain(CallDescriptorOf(node->op()), "descriptor",
721                               descriptor_matcher_, listener)) {
722       return false;
723     }
724     for (size_t i = 0; i < value_matchers_.size(); ++i) {
725       std::ostringstream ost;
726       ost << "value" << i;
727       if (!PrintMatchAndExplain(
728               NodeProperties::GetValueInput(node, static_cast<int>(i)),
729               ost.str(), value_matchers_[i], listener)) {
730         return false;
731       }
732     }
733     Node* effect_node = nullptr;
734     Node* control_node = nullptr;
735     if (NodeProperties::FirstEffectIndex(node) < node->InputCount()) {
736       effect_node = NodeProperties::GetEffectInput(node);
737     }
738     if (NodeProperties::FirstControlIndex(node) < node->InputCount()) {
739       control_node = NodeProperties::GetControlInput(node);
740     }
741     return (PrintMatchAndExplain(effect_node, "effect", effect_matcher_,
742                                  listener) &&
743             PrintMatchAndExplain(control_node, "control", control_matcher_,
744                                  listener));
745   }
746 
747  private:
748   const Matcher<const CallDescriptor*> descriptor_matcher_;
749   const std::vector<Matcher<Node*>> value_matchers_;
750   const Matcher<Node*> effect_matcher_;
751   const Matcher<Node*> control_matcher_;
752 };
753 
754 class IsTailCallMatcher final : public TestNodeMatcher {
755  public:
IsTailCallMatcher(const Matcher<CallDescriptor const * > & descriptor_matcher,const std::vector<Matcher<Node * >> & value_matchers,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)756   IsTailCallMatcher(const Matcher<CallDescriptor const*>& descriptor_matcher,
757                     const std::vector<Matcher<Node*>>& value_matchers,
758                     const Matcher<Node*>& effect_matcher,
759                     const Matcher<Node*>& control_matcher)
760       : TestNodeMatcher(IrOpcode::kTailCall),
761         descriptor_matcher_(descriptor_matcher),
762         value_matchers_(value_matchers),
763         effect_matcher_(effect_matcher),
764         control_matcher_(control_matcher) {}
765 
DescribeTo(std::ostream * os) const766   void DescribeTo(std::ostream* os) const final {
767     TestNodeMatcher::DescribeTo(os);
768     for (size_t i = 0; i < value_matchers_.size(); ++i) {
769       if (i == 0) {
770         *os << " whose value0 (";
771       } else {
772         *os << "), value" << i << " (";
773       }
774       value_matchers_[i].DescribeTo(os);
775     }
776     *os << "), effect (";
777     effect_matcher_.DescribeTo(os);
778     *os << ") and control (";
779     control_matcher_.DescribeTo(os);
780     *os << ")";
781   }
782 
MatchAndExplain(Node * node,MatchResultListener * listener) const783   bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
784     if (!TestNodeMatcher::MatchAndExplain(node, listener) ||
785         !PrintMatchAndExplain(CallDescriptorOf(node->op()), "descriptor",
786                               descriptor_matcher_, listener)) {
787       return false;
788     }
789     for (size_t i = 0; i < value_matchers_.size(); ++i) {
790       std::ostringstream ost;
791       ost << "value" << i;
792       if (!PrintMatchAndExplain(
793               NodeProperties::GetValueInput(node, static_cast<int>(i)),
794               ost.str(), value_matchers_[i], listener)) {
795         return false;
796       }
797     }
798     Node* effect_node = nullptr;
799     Node* control_node = nullptr;
800     if (NodeProperties::FirstEffectIndex(node) < node->InputCount()) {
801       effect_node = NodeProperties::GetEffectInput(node);
802     }
803     if (NodeProperties::FirstControlIndex(node) < node->InputCount()) {
804       control_node = NodeProperties::GetControlInput(node);
805     }
806     return (PrintMatchAndExplain(effect_node, "effect", effect_matcher_,
807                                  listener) &&
808             PrintMatchAndExplain(control_node, "control", control_matcher_,
809                                  listener));
810   }
811 
812  private:
813   const Matcher<CallDescriptor const*> descriptor_matcher_;
814   const std::vector<Matcher<Node*>> value_matchers_;
815   const Matcher<Node*> effect_matcher_;
816   const Matcher<Node*> control_matcher_;
817 };
818 
819 class IsSpeculativeBinopMatcher final : public TestNodeMatcher {
820  public:
IsSpeculativeBinopMatcher(IrOpcode::Value opcode,const Matcher<NumberOperationHint> & hint_matcher,const Matcher<Node * > & lhs_matcher,const Matcher<Node * > & rhs_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)821   IsSpeculativeBinopMatcher(IrOpcode::Value opcode,
822                             const Matcher<NumberOperationHint>& hint_matcher,
823                             const Matcher<Node*>& lhs_matcher,
824                             const Matcher<Node*>& rhs_matcher,
825                             const Matcher<Node*>& effect_matcher,
826                             const Matcher<Node*>& control_matcher)
827       : TestNodeMatcher(opcode),
828         hint_matcher_(hint_matcher),
829         lhs_matcher_(lhs_matcher),
830         rhs_matcher_(rhs_matcher),
831         effect_matcher_(effect_matcher),
832         control_matcher_(control_matcher) {}
833 
MatchAndExplain(Node * node,MatchResultListener * listener) const834   bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
835     return (TestNodeMatcher::MatchAndExplain(node, listener) &&
836             // TODO(bmeurer): The type parameter is currently ignored.
837             PrintMatchAndExplain(NumberOperationHintOf(node->op()), "hints",
838                                  hint_matcher_, listener) &&
839             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "lhs",
840                                  lhs_matcher_, listener) &&
841             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "rhs",
842                                  rhs_matcher_, listener) &&
843             PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
844                                  effect_matcher_, listener) &&
845             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
846                                  "control", control_matcher_, listener));
847   }
848 
849  private:
850   const Matcher<NumberOperationHint> hint_matcher_;
851   const Matcher<Type> type_matcher_;
852   const Matcher<Node*> lhs_matcher_;
853   const Matcher<Node*> rhs_matcher_;
854   const Matcher<Node*> effect_matcher_;
855   const Matcher<Node*> control_matcher_;
856 };
857 
858 class IsAllocateMatcher final : public TestNodeMatcher {
859  public:
IsAllocateMatcher(const Matcher<Node * > & size_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)860   IsAllocateMatcher(const Matcher<Node*>& size_matcher,
861                     const Matcher<Node*>& effect_matcher,
862                     const Matcher<Node*>& control_matcher)
863       : TestNodeMatcher(IrOpcode::kAllocate),
864         size_matcher_(size_matcher),
865         effect_matcher_(effect_matcher),
866         control_matcher_(control_matcher) {}
867 
MatchAndExplain(Node * node,MatchResultListener * listener) const868   bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
869     return (TestNodeMatcher::MatchAndExplain(node, listener) &&
870             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "size",
871                                  size_matcher_, listener) &&
872             PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
873                                  effect_matcher_, listener) &&
874             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
875                                  "control", control_matcher_, listener));
876   }
877 
878  private:
879   const Matcher<Node*> size_matcher_;
880   const Matcher<Node*> effect_matcher_;
881   const Matcher<Node*> control_matcher_;
882 };
883 
884 class IsLoadFieldMatcher final : public TestNodeMatcher {
885  public:
IsLoadFieldMatcher(const Matcher<FieldAccess> & access_matcher,const Matcher<Node * > & base_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)886   IsLoadFieldMatcher(const Matcher<FieldAccess>& access_matcher,
887                      const Matcher<Node*>& base_matcher,
888                      const Matcher<Node*>& effect_matcher,
889                      const Matcher<Node*>& control_matcher)
890       : TestNodeMatcher(IrOpcode::kLoadField),
891         access_matcher_(access_matcher),
892         base_matcher_(base_matcher),
893         effect_matcher_(effect_matcher),
894         control_matcher_(control_matcher) {}
895 
DescribeTo(std::ostream * os) const896   void DescribeTo(std::ostream* os) const final {
897     TestNodeMatcher::DescribeTo(os);
898     *os << " whose access (";
899     access_matcher_.DescribeTo(os);
900     *os << "), base (";
901     base_matcher_.DescribeTo(os);
902     *os << "), effect (";
903     effect_matcher_.DescribeTo(os);
904     *os << ") and control (";
905     control_matcher_.DescribeTo(os);
906     *os << ")";
907   }
908 
MatchAndExplain(Node * node,MatchResultListener * listener) const909   bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
910     return (TestNodeMatcher::MatchAndExplain(node, listener) &&
911             PrintMatchAndExplain(FieldAccessOf(node->op()), "access",
912                                  access_matcher_, listener) &&
913             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
914                                  base_matcher_, listener) &&
915             PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
916                                  effect_matcher_, listener) &&
917             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
918                                  "control", control_matcher_, listener));
919   }
920 
921  private:
922   const Matcher<FieldAccess> access_matcher_;
923   const Matcher<Node*> base_matcher_;
924   const Matcher<Node*> effect_matcher_;
925   const Matcher<Node*> control_matcher_;
926 };
927 
928 class IsStoreFieldMatcher final : public TestNodeMatcher {
929  public:
IsStoreFieldMatcher(const Matcher<FieldAccess> & access_matcher,const Matcher<Node * > & base_matcher,const Matcher<Node * > & value_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)930   IsStoreFieldMatcher(const Matcher<FieldAccess>& access_matcher,
931                       const Matcher<Node*>& base_matcher,
932                       const Matcher<Node*>& value_matcher,
933                       const Matcher<Node*>& effect_matcher,
934                       const Matcher<Node*>& control_matcher)
935       : TestNodeMatcher(IrOpcode::kStoreField),
936         access_matcher_(access_matcher),
937         base_matcher_(base_matcher),
938         value_matcher_(value_matcher),
939         effect_matcher_(effect_matcher),
940         control_matcher_(control_matcher) {}
941 
DescribeTo(std::ostream * os) const942   void DescribeTo(std::ostream* os) const final {
943     TestNodeMatcher::DescribeTo(os);
944     *os << " whose access (";
945     access_matcher_.DescribeTo(os);
946     *os << "), base (";
947     base_matcher_.DescribeTo(os);
948     *os << "), value (";
949     value_matcher_.DescribeTo(os);
950     *os << "), effect (";
951     effect_matcher_.DescribeTo(os);
952     *os << ") and control (";
953     control_matcher_.DescribeTo(os);
954     *os << ")";
955   }
956 
MatchAndExplain(Node * node,MatchResultListener * listener) const957   bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
958     return (TestNodeMatcher::MatchAndExplain(node, listener) &&
959             PrintMatchAndExplain(FieldAccessOf(node->op()), "access",
960                                  access_matcher_, listener) &&
961             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
962                                  base_matcher_, listener) &&
963             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
964                                  "value", value_matcher_, listener) &&
965             PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
966                                  effect_matcher_, listener) &&
967             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
968                                  "control", control_matcher_, listener));
969   }
970 
971  private:
972   const Matcher<FieldAccess> access_matcher_;
973   const Matcher<Node*> base_matcher_;
974   const Matcher<Node*> value_matcher_;
975   const Matcher<Node*> effect_matcher_;
976   const Matcher<Node*> control_matcher_;
977 };
978 
979 class IsLoadElementMatcher final : public TestNodeMatcher {
980  public:
IsLoadElementMatcher(const Matcher<ElementAccess> & access_matcher,const Matcher<Node * > & base_matcher,const Matcher<Node * > & index_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)981   IsLoadElementMatcher(const Matcher<ElementAccess>& access_matcher,
982                        const Matcher<Node*>& base_matcher,
983                        const Matcher<Node*>& index_matcher,
984                        const Matcher<Node*>& effect_matcher,
985                        const Matcher<Node*>& control_matcher)
986       : TestNodeMatcher(IrOpcode::kLoadElement),
987         access_matcher_(access_matcher),
988         base_matcher_(base_matcher),
989         index_matcher_(index_matcher),
990         effect_matcher_(effect_matcher),
991         control_matcher_(control_matcher) {}
992 
DescribeTo(std::ostream * os) const993   void DescribeTo(std::ostream* os) const final {
994     TestNodeMatcher::DescribeTo(os);
995     *os << " whose access (";
996     access_matcher_.DescribeTo(os);
997     *os << "), base (";
998     base_matcher_.DescribeTo(os);
999     *os << "), index (";
1000     index_matcher_.DescribeTo(os);
1001     *os << "), effect (";
1002     effect_matcher_.DescribeTo(os);
1003     *os << ") and control (";
1004     control_matcher_.DescribeTo(os);
1005     *os << ")";
1006   }
1007 
MatchAndExplain(Node * node,MatchResultListener * listener) const1008   bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
1009     return (TestNodeMatcher::MatchAndExplain(node, listener) &&
1010             PrintMatchAndExplain(ElementAccessOf(node->op()), "access",
1011                                  access_matcher_, listener) &&
1012             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
1013                                  base_matcher_, listener) &&
1014             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
1015                                  "index", index_matcher_, listener) &&
1016             PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
1017                                  effect_matcher_, listener) &&
1018             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
1019                                  "control", control_matcher_, listener));
1020   }
1021 
1022  private:
1023   const Matcher<ElementAccess> access_matcher_;
1024   const Matcher<Node*> base_matcher_;
1025   const Matcher<Node*> index_matcher_;
1026   const Matcher<Node*> effect_matcher_;
1027   const Matcher<Node*> control_matcher_;
1028 };
1029 
1030 class IsStoreElementMatcher final : public TestNodeMatcher {
1031  public:
IsStoreElementMatcher(const Matcher<ElementAccess> & access_matcher,const Matcher<Node * > & base_matcher,const Matcher<Node * > & index_matcher,const Matcher<Node * > & value_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)1032   IsStoreElementMatcher(const Matcher<ElementAccess>& access_matcher,
1033                         const Matcher<Node*>& base_matcher,
1034                         const Matcher<Node*>& index_matcher,
1035                         const Matcher<Node*>& value_matcher,
1036                         const Matcher<Node*>& effect_matcher,
1037                         const Matcher<Node*>& control_matcher)
1038       : TestNodeMatcher(IrOpcode::kStoreElement),
1039         access_matcher_(access_matcher),
1040         base_matcher_(base_matcher),
1041         index_matcher_(index_matcher),
1042         value_matcher_(value_matcher),
1043         effect_matcher_(effect_matcher),
1044         control_matcher_(control_matcher) {}
1045 
DescribeTo(std::ostream * os) const1046   void DescribeTo(std::ostream* os) const final {
1047     TestNodeMatcher::DescribeTo(os);
1048     *os << " whose access (";
1049     access_matcher_.DescribeTo(os);
1050     *os << "), base (";
1051     base_matcher_.DescribeTo(os);
1052     *os << "), index (";
1053     index_matcher_.DescribeTo(os);
1054     *os << "), value (";
1055     value_matcher_.DescribeTo(os);
1056     *os << "), effect (";
1057     effect_matcher_.DescribeTo(os);
1058     *os << ") and control (";
1059     control_matcher_.DescribeTo(os);
1060     *os << ")";
1061   }
1062 
MatchAndExplain(Node * node,MatchResultListener * listener) const1063   bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
1064     return (TestNodeMatcher::MatchAndExplain(node, listener) &&
1065             PrintMatchAndExplain(ElementAccessOf(node->op()), "access",
1066                                  access_matcher_, listener) &&
1067             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
1068                                  base_matcher_, listener) &&
1069             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
1070                                  "index", index_matcher_, listener) &&
1071             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2),
1072                                  "value", value_matcher_, listener) &&
1073             PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
1074                                  effect_matcher_, listener) &&
1075             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
1076                                  "control", control_matcher_, listener));
1077   }
1078 
1079  private:
1080   const Matcher<ElementAccess> access_matcher_;
1081   const Matcher<Node*> base_matcher_;
1082   const Matcher<Node*> index_matcher_;
1083   const Matcher<Node*> value_matcher_;
1084   const Matcher<Node*> effect_matcher_;
1085   const Matcher<Node*> control_matcher_;
1086 };
1087 
1088 #define LOAD_MATCHER(kLoad)                                                   \
1089   class Is##kLoad##Matcher final : public TestNodeMatcher {                   \
1090    public:                                                                    \
1091     Is##kLoad##Matcher(const Matcher<LoadRepresentation>& rep_matcher,        \
1092                        const Matcher<Node*>& base_matcher,                    \
1093                        const Matcher<Node*>& index_matcher,                   \
1094                        const Matcher<Node*>& effect_matcher,                  \
1095                        const Matcher<Node*>& control_matcher)                 \
1096         : TestNodeMatcher(IrOpcode::k##kLoad),                                \
1097           rep_matcher_(rep_matcher),                                          \
1098           base_matcher_(base_matcher),                                        \
1099           index_matcher_(index_matcher),                                      \
1100           effect_matcher_(effect_matcher),                                    \
1101           control_matcher_(control_matcher) {}                                \
1102                                                                               \
1103     void DescribeTo(std::ostream* os) const final {                           \
1104       TestNodeMatcher::DescribeTo(os);                                        \
1105       *os << " whose rep (";                                                  \
1106       rep_matcher_.DescribeTo(os);                                            \
1107       *os << "), base (";                                                     \
1108       base_matcher_.DescribeTo(os);                                           \
1109       *os << "), index (";                                                    \
1110       index_matcher_.DescribeTo(os);                                          \
1111       *os << "), effect (";                                                   \
1112       effect_matcher_.DescribeTo(os);                                         \
1113       *os << ") and control (";                                               \
1114       control_matcher_.DescribeTo(os);                                        \
1115       *os << ")";                                                             \
1116     }                                                                         \
1117                                                                               \
1118     bool MatchAndExplain(Node* node,                                          \
1119                          MatchResultListener* listener) const final {         \
1120       Node* effect_node = nullptr;                                            \
1121       Node* control_node = nullptr;                                           \
1122       if (NodeProperties::FirstEffectIndex(node) < node->InputCount()) {      \
1123         effect_node = NodeProperties::GetEffectInput(node);                   \
1124       }                                                                       \
1125       if (NodeProperties::FirstControlIndex(node) < node->InputCount()) {     \
1126         control_node = NodeProperties::GetControlInput(node);                 \
1127       }                                                                       \
1128       LoadRepresentation rep = IrOpcode::kLoadFromObject == node->opcode()    \
1129                                    ? ObjectAccessOf(node->op()).machine_type  \
1130                                    : LoadRepresentationOf(node->op());        \
1131       return (TestNodeMatcher::MatchAndExplain(node, listener) &&             \
1132               PrintMatchAndExplain(rep, "rep", rep_matcher_, listener) &&     \
1133               PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),    \
1134                                    "base", base_matcher_, listener) &&        \
1135               PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),    \
1136                                    "index", index_matcher_, listener) &&      \
1137               PrintMatchAndExplain(effect_node, "effect", effect_matcher_,    \
1138                                    listener) &&                               \
1139               PrintMatchAndExplain(control_node, "control", control_matcher_, \
1140                                    listener));                                \
1141     }                                                                         \
1142                                                                               \
1143    private:                                                                   \
1144     const Matcher<LoadRepresentation> rep_matcher_;                           \
1145     const Matcher<Node*> base_matcher_;                                       \
1146     const Matcher<Node*> index_matcher_;                                      \
1147     const Matcher<Node*> effect_matcher_;                                     \
1148     const Matcher<Node*> control_matcher_;                                    \
1149   };
1150 
1151 LOAD_MATCHER(Load)
1152 LOAD_MATCHER(UnalignedLoad)
1153 LOAD_MATCHER(LoadFromObject)
1154 
1155 class IsLoadImmutableMatcher final : public TestNodeMatcher {
1156  public:
IsLoadImmutableMatcher(const Matcher<LoadRepresentation> & rep_matcher,const Matcher<Node * > & base_matcher,const Matcher<Node * > & index_matcher)1157   IsLoadImmutableMatcher(const Matcher<LoadRepresentation>& rep_matcher,
1158                          const Matcher<Node*>& base_matcher,
1159                          const Matcher<Node*>& index_matcher)
1160       : TestNodeMatcher(IrOpcode::kLoadImmutable),
1161         rep_matcher_(rep_matcher),
1162         base_matcher_(base_matcher),
1163         index_matcher_(index_matcher) {}
1164 
DescribeTo(std::ostream * os) const1165   void DescribeTo(std::ostream* os) const final {
1166     TestNodeMatcher::DescribeTo(os);
1167     *os << " whose rep (";
1168     rep_matcher_.DescribeTo(os);
1169     *os << "), base (";
1170     base_matcher_.DescribeTo(os);
1171     *os << ") and index (";
1172     index_matcher_.DescribeTo(os);
1173     *os << ")";
1174   }
1175 
MatchAndExplain(Node * node,MatchResultListener * listener) const1176   bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
1177     LoadRepresentation rep = LoadRepresentationOf(node->op());
1178     return TestNodeMatcher::MatchAndExplain(node, listener) &&
1179            PrintMatchAndExplain(rep, "rep", rep_matcher_, listener) &&
1180            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
1181                                 base_matcher_, listener) &&
1182            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "index",
1183                                 index_matcher_, listener);
1184   }
1185 
1186  private:
1187   const Matcher<LoadRepresentation> rep_matcher_;
1188   const Matcher<Node*> base_matcher_;
1189   const Matcher<Node*> index_matcher_;
1190 };
1191 
1192 #define STORE_MATCHER(kStore, representation)                                 \
1193   class Is##kStore##Matcher final : public TestNodeMatcher {                  \
1194    public:                                                                    \
1195     Is##kStore##Matcher(const Matcher<representation>& rep_matcher,           \
1196                         const Matcher<Node*>& base_matcher,                   \
1197                         const Matcher<Node*>& index_matcher,                  \
1198                         const Matcher<Node*>& value_matcher,                  \
1199                         const Matcher<Node*>& effect_matcher,                 \
1200                         const Matcher<Node*>& control_matcher)                \
1201         : TestNodeMatcher(IrOpcode::k##kStore),                               \
1202           rep_matcher_(rep_matcher),                                          \
1203           base_matcher_(base_matcher),                                        \
1204           index_matcher_(index_matcher),                                      \
1205           value_matcher_(value_matcher),                                      \
1206           effect_matcher_(effect_matcher),                                    \
1207           control_matcher_(control_matcher) {}                                \
1208                                                                               \
1209     void DescribeTo(std::ostream* os) const final {                           \
1210       TestNodeMatcher::DescribeTo(os);                                        \
1211       *os << " whose rep (";                                                  \
1212       rep_matcher_.DescribeTo(os);                                            \
1213       *os << "), base (";                                                     \
1214       base_matcher_.DescribeTo(os);                                           \
1215       *os << "), index (";                                                    \
1216       index_matcher_.DescribeTo(os);                                          \
1217       *os << "), value (";                                                    \
1218       value_matcher_.DescribeTo(os);                                          \
1219       *os << "), effect (";                                                   \
1220       effect_matcher_.DescribeTo(os);                                         \
1221       *os << ") and control (";                                               \
1222       control_matcher_.DescribeTo(os);                                        \
1223       *os << ")";                                                             \
1224     }                                                                         \
1225                                                                               \
1226     bool MatchAndExplain(Node* node,                                          \
1227                          MatchResultListener* listener) const final {         \
1228       Node* effect_node = nullptr;                                            \
1229       Node* control_node = nullptr;                                           \
1230       if (NodeProperties::FirstEffectIndex(node) < node->InputCount()) {      \
1231         effect_node = NodeProperties::GetEffectInput(node);                   \
1232       }                                                                       \
1233       if (NodeProperties::FirstControlIndex(node) < node->InputCount()) {     \
1234         control_node = NodeProperties::GetControlInput(node);                 \
1235       }                                                                       \
1236       return (TestNodeMatcher::MatchAndExplain(node, listener) &&             \
1237               PrintMatchAndExplain(OpParameter<representation>(node->op()),   \
1238                                    "rep", rep_matcher_, listener) &&          \
1239               PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),    \
1240                                    "base", base_matcher_, listener) &&        \
1241               PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),    \
1242                                    "index", index_matcher_, listener) &&      \
1243               PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2),    \
1244                                    "value", value_matcher_, listener) &&      \
1245               PrintMatchAndExplain(effect_node, "effect", effect_matcher_,    \
1246                                    listener) &&                               \
1247               PrintMatchAndExplain(control_node, "control", control_matcher_, \
1248                                    listener));                                \
1249     }                                                                         \
1250                                                                               \
1251    private:                                                                   \
1252     const Matcher<representation> rep_matcher_;                               \
1253     const Matcher<Node*> base_matcher_;                                       \
1254     const Matcher<Node*> index_matcher_;                                      \
1255     const Matcher<Node*> value_matcher_;                                      \
1256     const Matcher<Node*> effect_matcher_;                                     \
1257     const Matcher<Node*> control_matcher_;                                    \
1258   };
1259 
1260 STORE_MATCHER(Store, StoreRepresentation)
1261 STORE_MATCHER(UnalignedStore, UnalignedStoreRepresentation)
1262 STORE_MATCHER(StoreToObject, ObjectAccess)
1263 
1264 class IsStackSlotMatcher final : public TestNodeMatcher {
1265  public:
IsStackSlotMatcher(const Matcher<StackSlotRepresentation> & rep_matcher)1266   explicit IsStackSlotMatcher(
1267       const Matcher<StackSlotRepresentation>& rep_matcher)
1268       : TestNodeMatcher(IrOpcode::kStackSlot), rep_matcher_(rep_matcher) {}
1269 
DescribeTo(std::ostream * os) const1270   void DescribeTo(std::ostream* os) const final {
1271     TestNodeMatcher::DescribeTo(os);
1272     *os << " whose rep (";
1273     rep_matcher_.DescribeTo(os);
1274     *os << ")";
1275   }
1276 
MatchAndExplain(Node * node,MatchResultListener * listener) const1277   bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
1278     return (TestNodeMatcher::MatchAndExplain(node, listener) &&
1279             PrintMatchAndExplain(StackSlotRepresentationOf(node->op()), "rep",
1280                                  rep_matcher_, listener));
1281   }
1282 
1283  private:
1284   const Matcher<StackSlotRepresentation> rep_matcher_;
1285 };
1286 
1287 class IsToNumberMatcher final : public TestNodeMatcher {
1288  public:
IsToNumberMatcher(const Matcher<Node * > & base_matcher,const Matcher<Node * > & context_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)1289   IsToNumberMatcher(const Matcher<Node*>& base_matcher,
1290                     const Matcher<Node*>& context_matcher,
1291                     const Matcher<Node*>& effect_matcher,
1292                     const Matcher<Node*>& control_matcher)
1293       : TestNodeMatcher(IrOpcode::kJSToNumber),
1294         base_matcher_(base_matcher),
1295         context_matcher_(context_matcher),
1296         effect_matcher_(effect_matcher),
1297         control_matcher_(control_matcher) {}
1298 
DescribeTo(std::ostream * os) const1299   void DescribeTo(std::ostream* os) const final {
1300     TestNodeMatcher::DescribeTo(os);
1301     *os << " whose base (";
1302     base_matcher_.DescribeTo(os);
1303     *os << "), context (";
1304     context_matcher_.DescribeTo(os);
1305     *os << "), effect (";
1306     effect_matcher_.DescribeTo(os);
1307     *os << ") and control (";
1308     control_matcher_.DescribeTo(os);
1309     *os << ")";
1310   }
1311 
MatchAndExplain(Node * node,MatchResultListener * listener) const1312   bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
1313     return (TestNodeMatcher::MatchAndExplain(node, listener) &&
1314             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
1315                                  base_matcher_, listener) &&
1316             PrintMatchAndExplain(NodeProperties::GetContextInput(node),
1317                                  "context", context_matcher_, listener) &&
1318             PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
1319                                  effect_matcher_, listener) &&
1320             PrintMatchAndExplain(NodeProperties::GetControlInput(node),
1321                                  "control", control_matcher_, listener));
1322   }
1323 
1324  private:
1325   const Matcher<Node*> base_matcher_;
1326   const Matcher<Node*> context_matcher_;
1327   const Matcher<Node*> effect_matcher_;
1328   const Matcher<Node*> control_matcher_;
1329 };
1330 
1331 class IsLoadContextMatcher final : public TestNodeMatcher {
1332  public:
IsLoadContextMatcher(const Matcher<ContextAccess> & access_matcher,const Matcher<Node * > & context_matcher)1333   IsLoadContextMatcher(const Matcher<ContextAccess>& access_matcher,
1334                        const Matcher<Node*>& context_matcher)
1335       : TestNodeMatcher(IrOpcode::kJSLoadContext),
1336         access_matcher_(access_matcher),
1337         context_matcher_(context_matcher) {}
1338 
DescribeTo(std::ostream * os) const1339   void DescribeTo(std::ostream* os) const final {
1340     TestNodeMatcher::DescribeTo(os);
1341     *os << " whose access (";
1342     access_matcher_.DescribeTo(os);
1343     *os << ") and context (";
1344     context_matcher_.DescribeTo(os);
1345     *os << ")";
1346   }
1347 
MatchAndExplain(Node * node,MatchResultListener * listener) const1348   bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
1349     return (TestNodeMatcher::MatchAndExplain(node, listener) &&
1350             PrintMatchAndExplain(ContextAccessOf(node->op()), "access",
1351                                  access_matcher_, listener) &&
1352             PrintMatchAndExplain(NodeProperties::GetContextInput(node),
1353                                  "context", context_matcher_, listener));
1354   }
1355 
1356  private:
1357   const Matcher<ContextAccess> access_matcher_;
1358   const Matcher<Node*> context_matcher_;
1359 };
1360 
1361 class IsQuadopMatcher final : public TestNodeMatcher {
1362  public:
IsQuadopMatcher(IrOpcode::Value opcode,const Matcher<Node * > & a_matcher,const Matcher<Node * > & b_matcher,const Matcher<Node * > & c_matcher,const Matcher<Node * > & d_matcher)1363   IsQuadopMatcher(IrOpcode::Value opcode, const Matcher<Node*>& a_matcher,
1364                   const Matcher<Node*>& b_matcher,
1365                   const Matcher<Node*>& c_matcher,
1366                   const Matcher<Node*>& d_matcher)
1367       : TestNodeMatcher(opcode),
1368         a_matcher_(a_matcher),
1369         b_matcher_(b_matcher),
1370         c_matcher_(c_matcher),
1371         d_matcher_(d_matcher) {}
1372 
DescribeTo(std::ostream * os) const1373   void DescribeTo(std::ostream* os) const final {
1374     TestNodeMatcher::DescribeTo(os);
1375     *os << " whose a (";
1376     a_matcher_.DescribeTo(os);
1377     *os << ") and b (";
1378     b_matcher_.DescribeTo(os);
1379     *os << ") and c (";
1380     c_matcher_.DescribeTo(os);
1381     *os << ") and d (";
1382     d_matcher_.DescribeTo(os);
1383     *os << ")";
1384   }
1385 
MatchAndExplain(Node * node,MatchResultListener * listener) const1386   bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
1387     return (TestNodeMatcher::MatchAndExplain(node, listener) &&
1388             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "a",
1389                                  a_matcher_, listener) &&
1390             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "b",
1391                                  b_matcher_, listener) &&
1392             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2), "c",
1393                                  c_matcher_, listener) &&
1394             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 3), "d",
1395                                  d_matcher_, listener));
1396   }
1397 
1398  private:
1399   const Matcher<Node*> a_matcher_;
1400   const Matcher<Node*> b_matcher_;
1401   const Matcher<Node*> c_matcher_;
1402   const Matcher<Node*> d_matcher_;
1403 };
1404 
1405 class IsTernopMatcher final : public TestNodeMatcher {
1406  public:
IsTernopMatcher(IrOpcode::Value opcode,const Matcher<Node * > & lhs_matcher,const Matcher<Node * > & mid_matcher,const Matcher<Node * > & rhs_matcher)1407   IsTernopMatcher(IrOpcode::Value opcode, const Matcher<Node*>& lhs_matcher,
1408                   const Matcher<Node*>& mid_matcher,
1409                   const Matcher<Node*>& rhs_matcher)
1410       : TestNodeMatcher(opcode),
1411         lhs_matcher_(lhs_matcher),
1412         mid_matcher_(mid_matcher),
1413         rhs_matcher_(rhs_matcher) {}
1414 
DescribeTo(std::ostream * os) const1415   void DescribeTo(std::ostream* os) const final {
1416     TestNodeMatcher::DescribeTo(os);
1417     *os << " whose lhs (";
1418     lhs_matcher_.DescribeTo(os);
1419     *os << ") and mid (";
1420     mid_matcher_.DescribeTo(os);
1421     *os << ") and rhs (";
1422     rhs_matcher_.DescribeTo(os);
1423     *os << ")";
1424   }
1425 
MatchAndExplain(Node * node,MatchResultListener * listener) const1426   bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
1427     return (TestNodeMatcher::MatchAndExplain(node, listener) &&
1428             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "lhs",
1429                                  lhs_matcher_, listener) &&
1430             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "mid",
1431                                  mid_matcher_, listener) &&
1432             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2), "rhs",
1433                                  rhs_matcher_, listener));
1434   }
1435 
1436  private:
1437   const Matcher<Node*> lhs_matcher_;
1438   const Matcher<Node*> mid_matcher_;
1439   const Matcher<Node*> rhs_matcher_;
1440 };
1441 
1442 class IsBinopMatcher final : public TestNodeMatcher {
1443  public:
IsBinopMatcher(IrOpcode::Value opcode,const Matcher<Node * > & lhs_matcher,const Matcher<Node * > & rhs_matcher)1444   IsBinopMatcher(IrOpcode::Value opcode, const Matcher<Node*>& lhs_matcher,
1445                  const Matcher<Node*>& rhs_matcher)
1446       : TestNodeMatcher(opcode),
1447         lhs_matcher_(lhs_matcher),
1448         rhs_matcher_(rhs_matcher) {}
1449 
DescribeTo(std::ostream * os) const1450   void DescribeTo(std::ostream* os) const final {
1451     TestNodeMatcher::DescribeTo(os);
1452     *os << " whose lhs (";
1453     lhs_matcher_.DescribeTo(os);
1454     *os << ") and rhs (";
1455     rhs_matcher_.DescribeTo(os);
1456     *os << ")";
1457   }
1458 
MatchAndExplain(Node * node,MatchResultListener * listener) const1459   bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
1460     return (TestNodeMatcher::MatchAndExplain(node, listener) &&
1461             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "lhs",
1462                                  lhs_matcher_, listener) &&
1463             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "rhs",
1464                                  rhs_matcher_, listener));
1465   }
1466 
1467  private:
1468   const Matcher<Node*> lhs_matcher_;
1469   const Matcher<Node*> rhs_matcher_;
1470 };
1471 
1472 class IsStringConcatMatcher final : public TestNodeMatcher {
1473  public:
IsStringConcatMatcher(const Matcher<Node * > & length_matcher,const Matcher<Node * > & lhs_matcher,const Matcher<Node * > & rhs_matcher)1474   IsStringConcatMatcher(const Matcher<Node*>& length_matcher,
1475                         const Matcher<Node*>& lhs_matcher,
1476                         const Matcher<Node*>& rhs_matcher)
1477       : TestNodeMatcher(IrOpcode::kStringConcat),
1478         length_matcher_(length_matcher),
1479         lhs_matcher_(lhs_matcher),
1480         rhs_matcher_(rhs_matcher) {}
1481 
DescribeTo(std::ostream * os) const1482   void DescribeTo(std::ostream* os) const final {
1483     TestNodeMatcher::DescribeTo(os);
1484     *os << " whose length (";
1485     length_matcher_.DescribeTo(os);
1486     *os << ") and lhs (";
1487     lhs_matcher_.DescribeTo(os);
1488     *os << ") and rhs (";
1489     rhs_matcher_.DescribeTo(os);
1490     *os << ")";
1491   }
1492 
MatchAndExplain(Node * node,MatchResultListener * listener) const1493   bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
1494     return (TestNodeMatcher::MatchAndExplain(node, listener) &&
1495             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
1496                                  "length", length_matcher_, listener) &&
1497             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "lhs",
1498                                  lhs_matcher_, listener) &&
1499             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2), "rhs",
1500                                  rhs_matcher_, listener));
1501   }
1502 
1503  private:
1504   const Matcher<Node*> length_matcher_;
1505   const Matcher<Node*> lhs_matcher_;
1506   const Matcher<Node*> rhs_matcher_;
1507 };
1508 
1509 class IsUnopMatcher final : public TestNodeMatcher {
1510  public:
IsUnopMatcher(IrOpcode::Value opcode,const Matcher<Node * > & input_matcher)1511   IsUnopMatcher(IrOpcode::Value opcode, const Matcher<Node*>& input_matcher)
1512       : TestNodeMatcher(opcode), input_matcher_(input_matcher) {}
1513 
DescribeTo(std::ostream * os) const1514   void DescribeTo(std::ostream* os) const final {
1515     TestNodeMatcher::DescribeTo(os);
1516     *os << " whose input (";
1517     input_matcher_.DescribeTo(os);
1518     *os << ")";
1519   }
1520 
MatchAndExplain(Node * node,MatchResultListener * listener) const1521   bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
1522     return (TestNodeMatcher::MatchAndExplain(node, listener) &&
1523             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
1524                                  "input", input_matcher_, listener));
1525   }
1526 
1527  private:
1528   const Matcher<Node*> input_matcher_;
1529 };
1530 
1531 class IsParameterMatcher final : public TestNodeMatcher {
1532  public:
IsParameterMatcher(const Matcher<int> & index_matcher)1533   explicit IsParameterMatcher(const Matcher<int>& index_matcher)
1534       : TestNodeMatcher(IrOpcode::kParameter), index_matcher_(index_matcher) {}
1535 
DescribeTo(std::ostream * os) const1536   void DescribeTo(std::ostream* os) const override {
1537     *os << "is a Parameter node with index(";
1538     index_matcher_.DescribeTo(os);
1539     *os << ")";
1540   }
1541 
MatchAndExplain(Node * node,MatchResultListener * listener) const1542   bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
1543     return (TestNodeMatcher::MatchAndExplain(node, listener) &&
1544             PrintMatchAndExplain(ParameterIndexOf(node->op()), "index",
1545                                  index_matcher_, listener));
1546   }
1547 
1548  private:
1549   const Matcher<int> index_matcher_;
1550 };
1551 
1552 }  // namespace
1553 
IsDead()1554 Matcher<Node*> IsDead() {
1555   return MakeMatcher(new TestNodeMatcher(IrOpcode::kDead));
1556 }
1557 
IsUnreachable()1558 Matcher<Node*> IsUnreachable() {
1559   return MakeMatcher(new TestNodeMatcher(IrOpcode::kUnreachable));
1560 }
1561 
IsThrow()1562 Matcher<Node*> IsThrow() {
1563   return MakeMatcher(new TestNodeMatcher(IrOpcode::kThrow));
1564 }
1565 
IsStart()1566 Matcher<Node*> IsStart() {
1567   return MakeMatcher(new TestNodeMatcher(IrOpcode::kStart));
1568 }
1569 
IsEnd(const Matcher<Node * > & control0_matcher)1570 Matcher<Node*> IsEnd(const Matcher<Node*>& control0_matcher) {
1571   return MakeMatcher(new IsControl1Matcher(IrOpcode::kEnd, control0_matcher));
1572 }
1573 
1574 
IsEnd(const Matcher<Node * > & control0_matcher,const Matcher<Node * > & control1_matcher)1575 Matcher<Node*> IsEnd(const Matcher<Node*>& control0_matcher,
1576                      const Matcher<Node*>& control1_matcher) {
1577   return MakeMatcher(new IsControl2Matcher(IrOpcode::kEnd, control0_matcher,
1578                                            control1_matcher));
1579 }
1580 
1581 
IsEnd(const Matcher<Node * > & control0_matcher,const Matcher<Node * > & control1_matcher,const Matcher<Node * > & control2_matcher)1582 Matcher<Node*> IsEnd(const Matcher<Node*>& control0_matcher,
1583                      const Matcher<Node*>& control1_matcher,
1584                      const Matcher<Node*>& control2_matcher) {
1585   return MakeMatcher(new IsControl3Matcher(IrOpcode::kEnd, control0_matcher,
1586                                            control1_matcher, control2_matcher));
1587 }
1588 
1589 
IsBranch(const Matcher<Node * > & value_matcher,const Matcher<Node * > & control_matcher)1590 Matcher<Node*> IsBranch(const Matcher<Node*>& value_matcher,
1591                         const Matcher<Node*>& control_matcher) {
1592   return MakeMatcher(new IsBranchMatcher(value_matcher, control_matcher));
1593 }
1594 
1595 
IsMerge(const Matcher<Node * > & control0_matcher,const Matcher<Node * > & control1_matcher)1596 Matcher<Node*> IsMerge(const Matcher<Node*>& control0_matcher,
1597                        const Matcher<Node*>& control1_matcher) {
1598   return MakeMatcher(new IsControl2Matcher(IrOpcode::kMerge, control0_matcher,
1599                                            control1_matcher));
1600 }
1601 
1602 
IsMerge(const Matcher<Node * > & control0_matcher,const Matcher<Node * > & control1_matcher,const Matcher<Node * > & control2_matcher)1603 Matcher<Node*> IsMerge(const Matcher<Node*>& control0_matcher,
1604                        const Matcher<Node*>& control1_matcher,
1605                        const Matcher<Node*>& control2_matcher) {
1606   return MakeMatcher(new IsControl3Matcher(IrOpcode::kMerge, control0_matcher,
1607                                            control1_matcher, control2_matcher));
1608 }
1609 
1610 
IsLoop(const Matcher<Node * > & control0_matcher,const Matcher<Node * > & control1_matcher)1611 Matcher<Node*> IsLoop(const Matcher<Node*>& control0_matcher,
1612                       const Matcher<Node*>& control1_matcher) {
1613   return MakeMatcher(new IsControl2Matcher(IrOpcode::kLoop, control0_matcher,
1614                                            control1_matcher));
1615 }
1616 
1617 
IsLoop(const Matcher<Node * > & control0_matcher,const Matcher<Node * > & control1_matcher,const Matcher<Node * > & control2_matcher)1618 Matcher<Node*> IsLoop(const Matcher<Node*>& control0_matcher,
1619                       const Matcher<Node*>& control1_matcher,
1620                       const Matcher<Node*>& control2_matcher) {
1621   return MakeMatcher(new IsControl3Matcher(IrOpcode::kLoop, control0_matcher,
1622                                            control1_matcher, control2_matcher));
1623 }
1624 
IsLoopExitValue(const Matcher<MachineRepresentation> rep_matcher,const Matcher<Node * > & value_matcher)1625 Matcher<Node*> IsLoopExitValue(const Matcher<MachineRepresentation> rep_matcher,
1626                                const Matcher<Node*>& value_matcher) {
1627   return MakeMatcher(new IsLoopExitValueMatcher(rep_matcher, value_matcher));
1628 }
1629 
IsIfTrue(const Matcher<Node * > & control_matcher)1630 Matcher<Node*> IsIfTrue(const Matcher<Node*>& control_matcher) {
1631   return MakeMatcher(new IsControl1Matcher(IrOpcode::kIfTrue, control_matcher));
1632 }
1633 
1634 
IsIfFalse(const Matcher<Node * > & control_matcher)1635 Matcher<Node*> IsIfFalse(const Matcher<Node*>& control_matcher) {
1636   return MakeMatcher(
1637       new IsControl1Matcher(IrOpcode::kIfFalse, control_matcher));
1638 }
1639 
1640 
IsIfSuccess(const Matcher<Node * > & control_matcher)1641 Matcher<Node*> IsIfSuccess(const Matcher<Node*>& control_matcher) {
1642   return MakeMatcher(
1643       new IsControl1Matcher(IrOpcode::kIfSuccess, control_matcher));
1644 }
1645 
1646 
IsSwitch(const Matcher<Node * > & value_matcher,const Matcher<Node * > & control_matcher)1647 Matcher<Node*> IsSwitch(const Matcher<Node*>& value_matcher,
1648                         const Matcher<Node*>& control_matcher) {
1649   return MakeMatcher(new IsSwitchMatcher(value_matcher, control_matcher));
1650 }
1651 
IsIfValue(const Matcher<IfValueParameters> & value_matcher,const Matcher<Node * > & control_matcher)1652 Matcher<Node*> IsIfValue(const Matcher<IfValueParameters>& value_matcher,
1653                          const Matcher<Node*>& control_matcher) {
1654   return MakeMatcher(new IsIfValueMatcher(value_matcher, control_matcher));
1655 }
1656 
1657 
IsIfDefault(const Matcher<Node * > & control_matcher)1658 Matcher<Node*> IsIfDefault(const Matcher<Node*>& control_matcher) {
1659   return MakeMatcher(
1660       new IsControl1Matcher(IrOpcode::kIfDefault, control_matcher));
1661 }
1662 
1663 
IsBeginRegion(const Matcher<Node * > & effect_matcher)1664 Matcher<Node*> IsBeginRegion(const Matcher<Node*>& effect_matcher) {
1665   return MakeMatcher(new IsBeginRegionMatcher(effect_matcher));
1666 }
1667 
1668 
IsFinishRegion(const Matcher<Node * > & value_matcher,const Matcher<Node * > & effect_matcher)1669 Matcher<Node*> IsFinishRegion(const Matcher<Node*>& value_matcher,
1670                               const Matcher<Node*>& effect_matcher) {
1671   return MakeMatcher(new IsFinishRegionMatcher(value_matcher, effect_matcher));
1672 }
1673 
1674 
IsReturn(const Matcher<Node * > & value_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)1675 Matcher<Node*> IsReturn(const Matcher<Node*>& value_matcher,
1676                         const Matcher<Node*>& effect_matcher,
1677                         const Matcher<Node*>& control_matcher) {
1678   return MakeMatcher(
1679       new IsReturnMatcher(value_matcher, effect_matcher, control_matcher));
1680 }
1681 
IsReturn2(const Matcher<Node * > & value_matcher,const Matcher<Node * > & value2_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)1682 Matcher<Node*> IsReturn2(const Matcher<Node*>& value_matcher,
1683                          const Matcher<Node*>& value2_matcher,
1684                          const Matcher<Node*>& effect_matcher,
1685                          const Matcher<Node*>& control_matcher) {
1686   return MakeMatcher(new IsReturnMatcher(value_matcher, value2_matcher,
1687                                          effect_matcher, control_matcher));
1688 }
1689 
IsTerminate(const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)1690 Matcher<Node*> IsTerminate(const Matcher<Node*>& effect_matcher,
1691                            const Matcher<Node*>& control_matcher) {
1692   return MakeMatcher(new IsTerminateMatcher(effect_matcher, control_matcher));
1693 }
1694 
IsTypeGuard(const Matcher<Node * > & value_matcher,const Matcher<Node * > & control_matcher)1695 Matcher<Node*> IsTypeGuard(const Matcher<Node*>& value_matcher,
1696                            const Matcher<Node*>& control_matcher) {
1697   return MakeMatcher(new IsTypeGuardMatcher(value_matcher, control_matcher));
1698 }
1699 
IsExternalConstant(const Matcher<ExternalReference> & value_matcher)1700 Matcher<Node*> IsExternalConstant(
1701     const Matcher<ExternalReference>& value_matcher) {
1702   return MakeMatcher(new IsConstantMatcher<ExternalReference>(
1703       IrOpcode::kExternalConstant, value_matcher));
1704 }
1705 
1706 
IsHeapConstant(Handle<HeapObject> value)1707 Matcher<Node*> IsHeapConstant(Handle<HeapObject> value) {
1708   return MakeMatcher(new IsConstantMatcher<Handle<HeapObject>>(
1709       IrOpcode::kHeapConstant, value));
1710 }
1711 
1712 
IsInt32Constant(const Matcher<int32_t> & value_matcher)1713 Matcher<Node*> IsInt32Constant(const Matcher<int32_t>& value_matcher) {
1714   return MakeMatcher(
1715       new IsConstantMatcher<int32_t>(IrOpcode::kInt32Constant, value_matcher));
1716 }
1717 
1718 
IsInt64Constant(const Matcher<int64_t> & value_matcher)1719 Matcher<Node*> IsInt64Constant(const Matcher<int64_t>& value_matcher) {
1720   return MakeMatcher(
1721       new IsConstantMatcher<int64_t>(IrOpcode::kInt64Constant, value_matcher));
1722 }
1723 
1724 
IsFloat32Constant(const Matcher<float> & value_matcher)1725 Matcher<Node*> IsFloat32Constant(const Matcher<float>& value_matcher) {
1726   return MakeMatcher(
1727       new IsConstantMatcher<float>(IrOpcode::kFloat32Constant, value_matcher));
1728 }
1729 
1730 
IsFloat64Constant(const Matcher<double> & value_matcher)1731 Matcher<Node*> IsFloat64Constant(const Matcher<double>& value_matcher) {
1732   return MakeMatcher(
1733       new IsConstantMatcher<double>(IrOpcode::kFloat64Constant, value_matcher));
1734 }
1735 
1736 
IsNumberConstant(const Matcher<double> & value_matcher)1737 Matcher<Node*> IsNumberConstant(const Matcher<double>& value_matcher) {
1738   return MakeMatcher(
1739       new IsConstantMatcher<double>(IrOpcode::kNumberConstant, value_matcher));
1740 }
1741 
IsPointerConstant(const Matcher<intptr_t> & value_matcher)1742 Matcher<Node*> IsPointerConstant(const Matcher<intptr_t>& value_matcher) {
1743   return MakeMatcher(new IsConstantMatcher<intptr_t>(IrOpcode::kPointerConstant,
1744                                                      value_matcher));
1745 }
1746 
IsSelect(const Matcher<MachineRepresentation> & type_matcher,const Matcher<Node * > & value0_matcher,const Matcher<Node * > & value1_matcher,const Matcher<Node * > & value2_matcher)1747 Matcher<Node*> IsSelect(const Matcher<MachineRepresentation>& type_matcher,
1748                         const Matcher<Node*>& value0_matcher,
1749                         const Matcher<Node*>& value1_matcher,
1750                         const Matcher<Node*>& value2_matcher) {
1751   return MakeMatcher(new IsSelectMatcher(type_matcher, value0_matcher,
1752                                          value1_matcher, value2_matcher));
1753 }
1754 
1755 
IsPhi(const Matcher<MachineRepresentation> & type_matcher,const Matcher<Node * > & value0_matcher,const Matcher<Node * > & value1_matcher,const Matcher<Node * > & merge_matcher)1756 Matcher<Node*> IsPhi(const Matcher<MachineRepresentation>& type_matcher,
1757                      const Matcher<Node*>& value0_matcher,
1758                      const Matcher<Node*>& value1_matcher,
1759                      const Matcher<Node*>& merge_matcher) {
1760   return MakeMatcher(new IsPhiMatcher(type_matcher, value0_matcher,
1761                                       value1_matcher, merge_matcher));
1762 }
1763 
1764 
IsPhi(const Matcher<MachineRepresentation> & type_matcher,const Matcher<Node * > & value0_matcher,const Matcher<Node * > & value1_matcher,const Matcher<Node * > & value2_matcher,const Matcher<Node * > & merge_matcher)1765 Matcher<Node*> IsPhi(const Matcher<MachineRepresentation>& type_matcher,
1766                      const Matcher<Node*>& value0_matcher,
1767                      const Matcher<Node*>& value1_matcher,
1768                      const Matcher<Node*>& value2_matcher,
1769                      const Matcher<Node*>& merge_matcher) {
1770   return MakeMatcher(new IsPhi2Matcher(type_matcher, value0_matcher,
1771                                        value1_matcher, value2_matcher,
1772                                        merge_matcher));
1773 }
1774 
1775 
IsEffectPhi(const Matcher<Node * > & effect0_matcher,const Matcher<Node * > & effect1_matcher,const Matcher<Node * > & merge_matcher)1776 Matcher<Node*> IsEffectPhi(const Matcher<Node*>& effect0_matcher,
1777                            const Matcher<Node*>& effect1_matcher,
1778                            const Matcher<Node*>& merge_matcher) {
1779   return MakeMatcher(
1780       new IsEffectPhiMatcher(effect0_matcher, effect1_matcher, merge_matcher));
1781 }
1782 
1783 
IsProjection(const Matcher<size_t> & index_matcher,const Matcher<Node * > & base_matcher)1784 Matcher<Node*> IsProjection(const Matcher<size_t>& index_matcher,
1785                             const Matcher<Node*>& base_matcher) {
1786   return MakeMatcher(new IsProjectionMatcher(index_matcher, base_matcher));
1787 }
1788 
IsCall(const Matcher<const CallDescriptor * > & descriptor_matcher,const Matcher<Node * > & value0_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)1789 Matcher<Node*> IsCall(const Matcher<const CallDescriptor*>& descriptor_matcher,
1790                       const Matcher<Node*>& value0_matcher,
1791                       const Matcher<Node*>& effect_matcher,
1792                       const Matcher<Node*>& control_matcher) {
1793   std::vector<Matcher<Node*>> value_matchers;
1794   value_matchers.push_back(value0_matcher);
1795   return MakeMatcher(new IsCallMatcher(descriptor_matcher, value_matchers,
1796                                        effect_matcher, control_matcher));
1797 }
1798 
IsCall(const Matcher<const CallDescriptor * > & descriptor_matcher,const Matcher<Node * > & value0_matcher,const Matcher<Node * > & value1_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)1799 Matcher<Node*> IsCall(const Matcher<const CallDescriptor*>& descriptor_matcher,
1800                       const Matcher<Node*>& value0_matcher,
1801                       const Matcher<Node*>& value1_matcher,
1802                       const Matcher<Node*>& effect_matcher,
1803                       const Matcher<Node*>& control_matcher) {
1804   std::vector<Matcher<Node*>> value_matchers;
1805   value_matchers.push_back(value0_matcher);
1806   value_matchers.push_back(value1_matcher);
1807   return MakeMatcher(new IsCallMatcher(descriptor_matcher, value_matchers,
1808                                        effect_matcher, control_matcher));
1809 }
1810 
1811 
IsCall(const Matcher<const CallDescriptor * > & descriptor_matcher,const Matcher<Node * > & value0_matcher,const Matcher<Node * > & value1_matcher,const Matcher<Node * > & value2_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)1812 Matcher<Node*> IsCall(const Matcher<const CallDescriptor*>& descriptor_matcher,
1813                       const Matcher<Node*>& value0_matcher,
1814                       const Matcher<Node*>& value1_matcher,
1815                       const Matcher<Node*>& value2_matcher,
1816                       const Matcher<Node*>& effect_matcher,
1817                       const Matcher<Node*>& control_matcher) {
1818   std::vector<Matcher<Node*>> value_matchers;
1819   value_matchers.push_back(value0_matcher);
1820   value_matchers.push_back(value1_matcher);
1821   value_matchers.push_back(value2_matcher);
1822   return MakeMatcher(new IsCallMatcher(descriptor_matcher, value_matchers,
1823                                        effect_matcher, control_matcher));
1824 }
1825 
1826 
IsCall(const Matcher<const CallDescriptor * > & descriptor_matcher,const Matcher<Node * > & value0_matcher,const Matcher<Node * > & value1_matcher,const Matcher<Node * > & value2_matcher,const Matcher<Node * > & value3_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)1827 Matcher<Node*> IsCall(const Matcher<const CallDescriptor*>& descriptor_matcher,
1828                       const Matcher<Node*>& value0_matcher,
1829                       const Matcher<Node*>& value1_matcher,
1830                       const Matcher<Node*>& value2_matcher,
1831                       const Matcher<Node*>& value3_matcher,
1832                       const Matcher<Node*>& effect_matcher,
1833                       const Matcher<Node*>& control_matcher) {
1834   std::vector<Matcher<Node*>> value_matchers;
1835   value_matchers.push_back(value0_matcher);
1836   value_matchers.push_back(value1_matcher);
1837   value_matchers.push_back(value2_matcher);
1838   value_matchers.push_back(value3_matcher);
1839   return MakeMatcher(new IsCallMatcher(descriptor_matcher, value_matchers,
1840                                        effect_matcher, control_matcher));
1841 }
1842 
1843 
IsCall(const Matcher<const CallDescriptor * > & descriptor_matcher,const Matcher<Node * > & value0_matcher,const Matcher<Node * > & value1_matcher,const Matcher<Node * > & value2_matcher,const Matcher<Node * > & value3_matcher,const Matcher<Node * > & value4_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)1844 Matcher<Node*> IsCall(const Matcher<const CallDescriptor*>& descriptor_matcher,
1845                       const Matcher<Node*>& value0_matcher,
1846                       const Matcher<Node*>& value1_matcher,
1847                       const Matcher<Node*>& value2_matcher,
1848                       const Matcher<Node*>& value3_matcher,
1849                       const Matcher<Node*>& value4_matcher,
1850                       const Matcher<Node*>& effect_matcher,
1851                       const Matcher<Node*>& control_matcher) {
1852   std::vector<Matcher<Node*>> value_matchers;
1853   value_matchers.push_back(value0_matcher);
1854   value_matchers.push_back(value1_matcher);
1855   value_matchers.push_back(value2_matcher);
1856   value_matchers.push_back(value3_matcher);
1857   value_matchers.push_back(value4_matcher);
1858   return MakeMatcher(new IsCallMatcher(descriptor_matcher, value_matchers,
1859                                        effect_matcher, control_matcher));
1860 }
1861 
1862 
IsCall(const Matcher<const CallDescriptor * > & descriptor_matcher,const Matcher<Node * > & value0_matcher,const Matcher<Node * > & value1_matcher,const Matcher<Node * > & value2_matcher,const Matcher<Node * > & value3_matcher,const Matcher<Node * > & value4_matcher,const Matcher<Node * > & value5_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)1863 Matcher<Node*> IsCall(const Matcher<const CallDescriptor*>& descriptor_matcher,
1864                       const Matcher<Node*>& value0_matcher,
1865                       const Matcher<Node*>& value1_matcher,
1866                       const Matcher<Node*>& value2_matcher,
1867                       const Matcher<Node*>& value3_matcher,
1868                       const Matcher<Node*>& value4_matcher,
1869                       const Matcher<Node*>& value5_matcher,
1870                       const Matcher<Node*>& effect_matcher,
1871                       const Matcher<Node*>& control_matcher) {
1872   std::vector<Matcher<Node*>> value_matchers;
1873   value_matchers.push_back(value0_matcher);
1874   value_matchers.push_back(value1_matcher);
1875   value_matchers.push_back(value2_matcher);
1876   value_matchers.push_back(value3_matcher);
1877   value_matchers.push_back(value4_matcher);
1878   value_matchers.push_back(value5_matcher);
1879   return MakeMatcher(new IsCallMatcher(descriptor_matcher, value_matchers,
1880                                        effect_matcher, control_matcher));
1881 }
1882 
1883 
IsCall(const Matcher<const CallDescriptor * > & descriptor_matcher,const Matcher<Node * > & value0_matcher,const Matcher<Node * > & value1_matcher,const Matcher<Node * > & value2_matcher,const Matcher<Node * > & value3_matcher,const Matcher<Node * > & value4_matcher,const Matcher<Node * > & value5_matcher,const Matcher<Node * > & value6_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)1884 Matcher<Node*> IsCall(
1885     const Matcher<const CallDescriptor*>& descriptor_matcher,
1886     const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher,
1887     const Matcher<Node*>& value2_matcher, const Matcher<Node*>& value3_matcher,
1888     const Matcher<Node*>& value4_matcher, const Matcher<Node*>& value5_matcher,
1889     const Matcher<Node*>& value6_matcher, const Matcher<Node*>& effect_matcher,
1890     const Matcher<Node*>& control_matcher) {
1891   std::vector<Matcher<Node*>> value_matchers;
1892   value_matchers.push_back(value0_matcher);
1893   value_matchers.push_back(value1_matcher);
1894   value_matchers.push_back(value2_matcher);
1895   value_matchers.push_back(value3_matcher);
1896   value_matchers.push_back(value4_matcher);
1897   value_matchers.push_back(value5_matcher);
1898   value_matchers.push_back(value6_matcher);
1899   return MakeMatcher(new IsCallMatcher(descriptor_matcher, value_matchers,
1900                                        effect_matcher, control_matcher));
1901 }
1902 
1903 
IsTailCall(const Matcher<CallDescriptor const * > & descriptor_matcher,const Matcher<Node * > & value0_matcher,const Matcher<Node * > & value1_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)1904 Matcher<Node*> IsTailCall(
1905     const Matcher<CallDescriptor const*>& descriptor_matcher,
1906     const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher,
1907     const Matcher<Node*>& effect_matcher,
1908     const Matcher<Node*>& control_matcher) {
1909   std::vector<Matcher<Node*>> value_matchers;
1910   value_matchers.push_back(value0_matcher);
1911   value_matchers.push_back(value1_matcher);
1912   return MakeMatcher(new IsTailCallMatcher(descriptor_matcher, value_matchers,
1913                                            effect_matcher, control_matcher));
1914 }
1915 
1916 
IsTailCall(const Matcher<CallDescriptor const * > & descriptor_matcher,const Matcher<Node * > & value0_matcher,const Matcher<Node * > & value1_matcher,const Matcher<Node * > & value2_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)1917 Matcher<Node*> IsTailCall(
1918     const Matcher<CallDescriptor const*>& descriptor_matcher,
1919     const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher,
1920     const Matcher<Node*>& value2_matcher, const Matcher<Node*>& effect_matcher,
1921     const Matcher<Node*>& control_matcher) {
1922   std::vector<Matcher<Node*>> value_matchers;
1923   value_matchers.push_back(value0_matcher);
1924   value_matchers.push_back(value1_matcher);
1925   value_matchers.push_back(value2_matcher);
1926   return MakeMatcher(new IsTailCallMatcher(descriptor_matcher, value_matchers,
1927                                            effect_matcher, control_matcher));
1928 }
1929 
1930 
IsTailCall(const Matcher<CallDescriptor const * > & descriptor_matcher,const Matcher<Node * > & value0_matcher,const Matcher<Node * > & value1_matcher,const Matcher<Node * > & value2_matcher,const Matcher<Node * > & value3_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)1931 Matcher<Node*> IsTailCall(
1932     const Matcher<CallDescriptor const*>& descriptor_matcher,
1933     const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher,
1934     const Matcher<Node*>& value2_matcher, const Matcher<Node*>& value3_matcher,
1935     const Matcher<Node*>& effect_matcher,
1936     const Matcher<Node*>& control_matcher) {
1937   std::vector<Matcher<Node*>> value_matchers;
1938   value_matchers.push_back(value0_matcher);
1939   value_matchers.push_back(value1_matcher);
1940   value_matchers.push_back(value2_matcher);
1941   value_matchers.push_back(value3_matcher);
1942   return MakeMatcher(new IsTailCallMatcher(descriptor_matcher, value_matchers,
1943                                            effect_matcher, control_matcher));
1944 }
1945 
1946 
IsTailCall(const Matcher<CallDescriptor const * > & descriptor_matcher,const Matcher<Node * > & value0_matcher,const Matcher<Node * > & value1_matcher,const Matcher<Node * > & value2_matcher,const Matcher<Node * > & value3_matcher,const Matcher<Node * > & value4_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)1947 Matcher<Node*> IsTailCall(
1948     const Matcher<CallDescriptor const*>& descriptor_matcher,
1949     const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher,
1950     const Matcher<Node*>& value2_matcher, const Matcher<Node*>& value3_matcher,
1951     const Matcher<Node*>& value4_matcher, const Matcher<Node*>& effect_matcher,
1952     const Matcher<Node*>& control_matcher) {
1953   std::vector<Matcher<Node*>> value_matchers;
1954   value_matchers.push_back(value0_matcher);
1955   value_matchers.push_back(value1_matcher);
1956   value_matchers.push_back(value2_matcher);
1957   value_matchers.push_back(value3_matcher);
1958   value_matchers.push_back(value4_matcher);
1959   return MakeMatcher(new IsTailCallMatcher(descriptor_matcher, value_matchers,
1960                                            effect_matcher, control_matcher));
1961 }
1962 
1963 
IsTailCall(const Matcher<CallDescriptor const * > & descriptor_matcher,const Matcher<Node * > & value0_matcher,const Matcher<Node * > & value1_matcher,const Matcher<Node * > & value2_matcher,const Matcher<Node * > & value3_matcher,const Matcher<Node * > & value4_matcher,const Matcher<Node * > & value5_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)1964 Matcher<Node*> IsTailCall(
1965     const Matcher<CallDescriptor const*>& descriptor_matcher,
1966     const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher,
1967     const Matcher<Node*>& value2_matcher, const Matcher<Node*>& value3_matcher,
1968     const Matcher<Node*>& value4_matcher, const Matcher<Node*>& value5_matcher,
1969     const Matcher<Node*>& effect_matcher,
1970     const Matcher<Node*>& control_matcher) {
1971   std::vector<Matcher<Node*>> value_matchers;
1972   value_matchers.push_back(value0_matcher);
1973   value_matchers.push_back(value1_matcher);
1974   value_matchers.push_back(value2_matcher);
1975   value_matchers.push_back(value3_matcher);
1976   value_matchers.push_back(value4_matcher);
1977   value_matchers.push_back(value5_matcher);
1978   return MakeMatcher(new IsTailCallMatcher(descriptor_matcher, value_matchers,
1979                                            effect_matcher, control_matcher));
1980 }
1981 
1982 
IsTailCall(const Matcher<CallDescriptor const * > & descriptor_matcher,const Matcher<Node * > & value0_matcher,const Matcher<Node * > & value1_matcher,const Matcher<Node * > & value2_matcher,const Matcher<Node * > & value3_matcher,const Matcher<Node * > & value4_matcher,const Matcher<Node * > & value5_matcher,const Matcher<Node * > & value6_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)1983 Matcher<Node*> IsTailCall(
1984     const Matcher<CallDescriptor const*>& descriptor_matcher,
1985     const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher,
1986     const Matcher<Node*>& value2_matcher, const Matcher<Node*>& value3_matcher,
1987     const Matcher<Node*>& value4_matcher, const Matcher<Node*>& value5_matcher,
1988     const Matcher<Node*>& value6_matcher, const Matcher<Node*>& effect_matcher,
1989     const Matcher<Node*>& control_matcher) {
1990   std::vector<Matcher<Node*>> value_matchers;
1991   value_matchers.push_back(value0_matcher);
1992   value_matchers.push_back(value1_matcher);
1993   value_matchers.push_back(value2_matcher);
1994   value_matchers.push_back(value3_matcher);
1995   value_matchers.push_back(value4_matcher);
1996   value_matchers.push_back(value5_matcher);
1997   value_matchers.push_back(value6_matcher);
1998   return MakeMatcher(new IsTailCallMatcher(descriptor_matcher, value_matchers,
1999                                            effect_matcher, control_matcher));
2000 }
2001 
2002 
IsTailCall(const Matcher<CallDescriptor const * > & descriptor_matcher,const Matcher<Node * > & value0_matcher,const Matcher<Node * > & value1_matcher,const Matcher<Node * > & value2_matcher,const Matcher<Node * > & value3_matcher,const Matcher<Node * > & value4_matcher,const Matcher<Node * > & value5_matcher,const Matcher<Node * > & value6_matcher,const Matcher<Node * > & value7_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)2003 Matcher<Node*> IsTailCall(
2004     const Matcher<CallDescriptor const*>& descriptor_matcher,
2005     const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher,
2006     const Matcher<Node*>& value2_matcher, const Matcher<Node*>& value3_matcher,
2007     const Matcher<Node*>& value4_matcher, const Matcher<Node*>& value5_matcher,
2008     const Matcher<Node*>& value6_matcher, const Matcher<Node*>& value7_matcher,
2009     const Matcher<Node*>& effect_matcher,
2010     const Matcher<Node*>& control_matcher) {
2011   std::vector<Matcher<Node*>> value_matchers;
2012   value_matchers.push_back(value0_matcher);
2013   value_matchers.push_back(value1_matcher);
2014   value_matchers.push_back(value2_matcher);
2015   value_matchers.push_back(value3_matcher);
2016   value_matchers.push_back(value4_matcher);
2017   value_matchers.push_back(value5_matcher);
2018   value_matchers.push_back(value6_matcher);
2019   value_matchers.push_back(value7_matcher);
2020   return MakeMatcher(new IsTailCallMatcher(descriptor_matcher, value_matchers,
2021                                            effect_matcher, control_matcher));
2022 }
2023 
2024 #define DEFINE_SPECULATIVE_BINOP_MATCHER(opcode)                              \
2025   Matcher<Node*> Is##opcode(const Matcher<NumberOperationHint>& hint_matcher, \
2026                             const Matcher<Node*>& lhs_matcher,                \
2027                             const Matcher<Node*>& rhs_matcher,                \
2028                             const Matcher<Node*>& effect_matcher,             \
2029                             const Matcher<Node*>& control_matcher) {          \
2030     return MakeMatcher(new IsSpeculativeBinopMatcher(                         \
2031         IrOpcode::k##opcode, hint_matcher, lhs_matcher, rhs_matcher,          \
2032         effect_matcher, control_matcher));                                    \
2033   }
2034 SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DEFINE_SPECULATIVE_BINOP_MATCHER)
DEFINE_SPECULATIVE_BINOP_MATCHER(SpeculativeNumberEqual)2035 DEFINE_SPECULATIVE_BINOP_MATCHER(SpeculativeNumberEqual)
2036 DEFINE_SPECULATIVE_BINOP_MATCHER(SpeculativeNumberLessThan)
2037 DEFINE_SPECULATIVE_BINOP_MATCHER(SpeculativeNumberLessThanOrEqual)
2038 #undef DEFINE_SPECULATIVE_BINOP_MATCHER
2039 
2040 Matcher<Node*> IsStringConcat(const Matcher<Node*>& length_matcher,
2041                               const Matcher<Node*>& lhs_matcher,
2042                               const Matcher<Node*>& rhs_matcher) {
2043   return MakeMatcher(
2044       new IsStringConcatMatcher(length_matcher, lhs_matcher, rhs_matcher));
2045 }
2046 
IsAllocate(const Matcher<Node * > & size_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)2047 Matcher<Node*> IsAllocate(const Matcher<Node*>& size_matcher,
2048                           const Matcher<Node*>& effect_matcher,
2049                           const Matcher<Node*>& control_matcher) {
2050   return MakeMatcher(
2051       new IsAllocateMatcher(size_matcher, effect_matcher, control_matcher));
2052 }
2053 
2054 
IsLoadField(const Matcher<FieldAccess> & access_matcher,const Matcher<Node * > & base_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)2055 Matcher<Node*> IsLoadField(const Matcher<FieldAccess>& access_matcher,
2056                            const Matcher<Node*>& base_matcher,
2057                            const Matcher<Node*>& effect_matcher,
2058                            const Matcher<Node*>& control_matcher) {
2059   return MakeMatcher(new IsLoadFieldMatcher(access_matcher, base_matcher,
2060                                             effect_matcher, control_matcher));
2061 }
2062 
2063 
IsStoreField(const Matcher<FieldAccess> & access_matcher,const Matcher<Node * > & base_matcher,const Matcher<Node * > & value_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)2064 Matcher<Node*> IsStoreField(const Matcher<FieldAccess>& access_matcher,
2065                             const Matcher<Node*>& base_matcher,
2066                             const Matcher<Node*>& value_matcher,
2067                             const Matcher<Node*>& effect_matcher,
2068                             const Matcher<Node*>& control_matcher) {
2069   return MakeMatcher(new IsStoreFieldMatcher(access_matcher, base_matcher,
2070                                              value_matcher, effect_matcher,
2071                                              control_matcher));
2072 }
2073 
IsLoadElement(const Matcher<ElementAccess> & access_matcher,const Matcher<Node * > & base_matcher,const Matcher<Node * > & index_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)2074 Matcher<Node*> IsLoadElement(const Matcher<ElementAccess>& access_matcher,
2075                              const Matcher<Node*>& base_matcher,
2076                              const Matcher<Node*>& index_matcher,
2077                              const Matcher<Node*>& effect_matcher,
2078                              const Matcher<Node*>& control_matcher) {
2079   return MakeMatcher(new IsLoadElementMatcher(access_matcher, base_matcher,
2080                                               index_matcher, effect_matcher,
2081                                               control_matcher));
2082 }
2083 
2084 
IsStoreElement(const Matcher<ElementAccess> & access_matcher,const Matcher<Node * > & base_matcher,const Matcher<Node * > & index_matcher,const Matcher<Node * > & value_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)2085 Matcher<Node*> IsStoreElement(const Matcher<ElementAccess>& access_matcher,
2086                               const Matcher<Node*>& base_matcher,
2087                               const Matcher<Node*>& index_matcher,
2088                               const Matcher<Node*>& value_matcher,
2089                               const Matcher<Node*>& effect_matcher,
2090                               const Matcher<Node*>& control_matcher) {
2091   return MakeMatcher(new IsStoreElementMatcher(
2092       access_matcher, base_matcher, index_matcher, value_matcher,
2093       effect_matcher, control_matcher));
2094 }
2095 
IsLoad(const Matcher<LoadRepresentation> & rep_matcher,const Matcher<Node * > & base_matcher,const Matcher<Node * > & index_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)2096 Matcher<Node*> IsLoad(const Matcher<LoadRepresentation>& rep_matcher,
2097                       const Matcher<Node*>& base_matcher,
2098                       const Matcher<Node*>& index_matcher,
2099                       const Matcher<Node*>& effect_matcher,
2100                       const Matcher<Node*>& control_matcher) {
2101   return MakeMatcher(new IsLoadMatcher(rep_matcher, base_matcher, index_matcher,
2102                                        effect_matcher, control_matcher));
2103 }
2104 
IsUnalignedLoad(const Matcher<LoadRepresentation> & rep_matcher,const Matcher<Node * > & base_matcher,const Matcher<Node * > & index_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)2105 Matcher<Node*> IsUnalignedLoad(const Matcher<LoadRepresentation>& rep_matcher,
2106                                const Matcher<Node*>& base_matcher,
2107                                const Matcher<Node*>& index_matcher,
2108                                const Matcher<Node*>& effect_matcher,
2109                                const Matcher<Node*>& control_matcher) {
2110   return MakeMatcher(new IsUnalignedLoadMatcher(rep_matcher, base_matcher,
2111                                                 index_matcher, effect_matcher,
2112                                                 control_matcher));
2113 }
2114 
IsLoadFromObject(const Matcher<LoadRepresentation> & rep_matcher,const Matcher<Node * > & base_matcher,const Matcher<Node * > & index_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)2115 Matcher<Node*> IsLoadFromObject(const Matcher<LoadRepresentation>& rep_matcher,
2116                                 const Matcher<Node*>& base_matcher,
2117                                 const Matcher<Node*>& index_matcher,
2118                                 const Matcher<Node*>& effect_matcher,
2119                                 const Matcher<Node*>& control_matcher) {
2120   return MakeMatcher(new IsLoadFromObjectMatcher(rep_matcher, base_matcher,
2121                                                  index_matcher, effect_matcher,
2122                                                  control_matcher));
2123 }
2124 
IsLoadImmutable(const Matcher<LoadRepresentation> & rep_matcher,const Matcher<Node * > & base_matcher,const Matcher<Node * > & index_matcher)2125 Matcher<Node*> IsLoadImmutable(const Matcher<LoadRepresentation>& rep_matcher,
2126                                const Matcher<Node*>& base_matcher,
2127                                const Matcher<Node*>& index_matcher) {
2128   return MakeMatcher(
2129       new IsLoadImmutableMatcher(rep_matcher, base_matcher, index_matcher));
2130 }
2131 
IsStore(const Matcher<StoreRepresentation> & rep_matcher,const Matcher<Node * > & base_matcher,const Matcher<Node * > & index_matcher,const Matcher<Node * > & value_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)2132 Matcher<Node*> IsStore(const Matcher<StoreRepresentation>& rep_matcher,
2133                        const Matcher<Node*>& base_matcher,
2134                        const Matcher<Node*>& index_matcher,
2135                        const Matcher<Node*>& value_matcher,
2136                        const Matcher<Node*>& effect_matcher,
2137                        const Matcher<Node*>& control_matcher) {
2138   return MakeMatcher(new IsStoreMatcher(rep_matcher, base_matcher,
2139                                         index_matcher, value_matcher,
2140                                         effect_matcher, control_matcher));
2141 }
2142 
IsUnalignedStore(const Matcher<UnalignedStoreRepresentation> & rep_matcher,const Matcher<Node * > & base_matcher,const Matcher<Node * > & index_matcher,const Matcher<Node * > & value_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)2143 Matcher<Node*> IsUnalignedStore(
2144     const Matcher<UnalignedStoreRepresentation>& rep_matcher,
2145     const Matcher<Node*>& base_matcher, const Matcher<Node*>& index_matcher,
2146     const Matcher<Node*>& value_matcher, const Matcher<Node*>& effect_matcher,
2147     const Matcher<Node*>& control_matcher) {
2148   return MakeMatcher(new IsUnalignedStoreMatcher(
2149       rep_matcher, base_matcher, index_matcher, value_matcher, effect_matcher,
2150       control_matcher));
2151 }
2152 
IsStoreToObject(const Matcher<ObjectAccess> & rep_matcher,const Matcher<Node * > & base_matcher,const Matcher<Node * > & index_matcher,const Matcher<Node * > & value_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)2153 Matcher<Node*> IsStoreToObject(const Matcher<ObjectAccess>& rep_matcher,
2154                                const Matcher<Node*>& base_matcher,
2155                                const Matcher<Node*>& index_matcher,
2156                                const Matcher<Node*>& value_matcher,
2157                                const Matcher<Node*>& effect_matcher,
2158                                const Matcher<Node*>& control_matcher) {
2159   return MakeMatcher(new IsStoreToObjectMatcher(
2160       rep_matcher, base_matcher, index_matcher, value_matcher, effect_matcher,
2161       control_matcher));
2162 }
2163 
IsStackSlot(const Matcher<StackSlotRepresentation> & rep_matcher)2164 Matcher<Node*> IsStackSlot(
2165     const Matcher<StackSlotRepresentation>& rep_matcher) {
2166   return MakeMatcher(new IsStackSlotMatcher(rep_matcher));
2167 }
2168 
IsToNumber(const Matcher<Node * > & base_matcher,const Matcher<Node * > & context_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)2169 Matcher<Node*> IsToNumber(const Matcher<Node*>& base_matcher,
2170                           const Matcher<Node*>& context_matcher,
2171                           const Matcher<Node*>& effect_matcher,
2172                           const Matcher<Node*>& control_matcher) {
2173   return MakeMatcher(new IsToNumberMatcher(base_matcher, context_matcher,
2174                                            effect_matcher, control_matcher));
2175 }
2176 
2177 
IsLoadContext(const Matcher<ContextAccess> & access_matcher,const Matcher<Node * > & context_matcher)2178 Matcher<Node*> IsLoadContext(const Matcher<ContextAccess>& access_matcher,
2179                              const Matcher<Node*>& context_matcher) {
2180   return MakeMatcher(new IsLoadContextMatcher(access_matcher, context_matcher));
2181 }
2182 
2183 
IsParameter(const Matcher<int> index_matcher)2184 Matcher<Node*> IsParameter(const Matcher<int> index_matcher) {
2185   return MakeMatcher(new IsParameterMatcher(index_matcher));
2186 }
2187 
IsLoadFramePointer()2188 Matcher<Node*> IsLoadFramePointer() {
2189   return MakeMatcher(new TestNodeMatcher(IrOpcode::kLoadFramePointer));
2190 }
2191 
IsLoadParentFramePointer()2192 Matcher<Node*> IsLoadParentFramePointer() {
2193   return MakeMatcher(new TestNodeMatcher(IrOpcode::kLoadParentFramePointer));
2194 }
2195 
2196 #define IS_QUADOP_MATCHER(Name)                                               \
2197   Matcher<Node*> Is##Name(                                                    \
2198       const Matcher<Node*>& a_matcher, const Matcher<Node*>& b_matcher,       \
2199       const Matcher<Node*>& c_matcher, const Matcher<Node*>& d_matcher) {     \
2200     return MakeMatcher(new IsQuadopMatcher(IrOpcode::k##Name, a_matcher,      \
2201                                            b_matcher, c_matcher, d_matcher)); \
2202   }
2203 
2204 IS_QUADOP_MATCHER(Int32PairAdd)
IS_QUADOP_MATCHER(Int32PairSub)2205 IS_QUADOP_MATCHER(Int32PairSub)
2206 IS_QUADOP_MATCHER(Int32PairMul)
2207 
2208 #define IS_TERNOP_MATCHER(Name)                                            \
2209   Matcher<Node*> Is##Name(const Matcher<Node*>& lhs_matcher,               \
2210                           const Matcher<Node*>& mid_matcher,               \
2211                           const Matcher<Node*>& rhs_matcher) {             \
2212     return MakeMatcher(new IsTernopMatcher(IrOpcode::k##Name, lhs_matcher, \
2213                                            mid_matcher, rhs_matcher));     \
2214   }
2215 
2216 IS_TERNOP_MATCHER(Word32PairShl)
2217 IS_TERNOP_MATCHER(Word32PairShr)
2218 IS_TERNOP_MATCHER(Word32PairSar)
2219 
2220 #define IS_BINOP_MATCHER(Name)                                            \
2221   Matcher<Node*> Is##Name(const Matcher<Node*>& lhs_matcher,              \
2222                           const Matcher<Node*>& rhs_matcher) {            \
2223     return MakeMatcher(                                                   \
2224         new IsBinopMatcher(IrOpcode::k##Name, lhs_matcher, rhs_matcher)); \
2225   }
2226 IS_BINOP_MATCHER(NumberEqual)
2227 IS_BINOP_MATCHER(NumberLessThan)
2228 IS_BINOP_MATCHER(NumberSubtract)
2229 IS_BINOP_MATCHER(NumberMultiply)
2230 IS_BINOP_MATCHER(NumberShiftLeft)
2231 IS_BINOP_MATCHER(NumberShiftRight)
2232 IS_BINOP_MATCHER(NumberShiftRightLogical)
2233 IS_BINOP_MATCHER(NumberImul)
2234 IS_BINOP_MATCHER(NumberAtan2)
2235 IS_BINOP_MATCHER(NumberMax)
2236 IS_BINOP_MATCHER(NumberMin)
2237 IS_BINOP_MATCHER(NumberPow)
2238 IS_BINOP_MATCHER(ReferenceEqual)
2239 IS_BINOP_MATCHER(Word32And)
2240 IS_BINOP_MATCHER(Word32Or)
2241 IS_BINOP_MATCHER(Word32Xor)
2242 IS_BINOP_MATCHER(Word32Sar)
2243 IS_BINOP_MATCHER(Word32Shl)
2244 IS_BINOP_MATCHER(Word32Shr)
2245 IS_BINOP_MATCHER(Word32Ror)
2246 IS_BINOP_MATCHER(Word32Equal)
2247 IS_BINOP_MATCHER(Word64And)
2248 IS_BINOP_MATCHER(Word64Or)
2249 IS_BINOP_MATCHER(Word64Xor)
2250 IS_BINOP_MATCHER(Word64Sar)
2251 IS_BINOP_MATCHER(Word64Shl)
2252 IS_BINOP_MATCHER(Word64Shr)
2253 IS_BINOP_MATCHER(Word64Equal)
2254 IS_BINOP_MATCHER(Int32AddWithOverflow)
2255 IS_BINOP_MATCHER(Int32SubWithOverflow)
2256 IS_BINOP_MATCHER(Int32Add)
2257 IS_BINOP_MATCHER(Int32Div)
2258 IS_BINOP_MATCHER(Int32Sub)
2259 IS_BINOP_MATCHER(Int32Mul)
2260 IS_BINOP_MATCHER(Int32MulHigh)
2261 IS_BINOP_MATCHER(Int32LessThan)
2262 IS_BINOP_MATCHER(Uint32LessThan)
2263 IS_BINOP_MATCHER(Uint32LessThanOrEqual)
2264 IS_BINOP_MATCHER(Int64Add)
2265 IS_BINOP_MATCHER(Int64Div)
2266 IS_BINOP_MATCHER(Int64Sub)
2267 IS_BINOP_MATCHER(Int64Mul)
2268 IS_BINOP_MATCHER(Int64LessThan)
2269 IS_BINOP_MATCHER(Uint64LessThan)
2270 IS_BINOP_MATCHER(JSAdd)
2271 IS_BINOP_MATCHER(JSParseInt)
2272 IS_BINOP_MATCHER(Float32Equal)
2273 IS_BINOP_MATCHER(Float32LessThan)
2274 IS_BINOP_MATCHER(Float32LessThanOrEqual)
2275 IS_BINOP_MATCHER(Float64Max)
2276 IS_BINOP_MATCHER(Float64Min)
2277 IS_BINOP_MATCHER(Float64Add)
2278 IS_BINOP_MATCHER(Float64Sub)
2279 IS_BINOP_MATCHER(Float64Mul)
2280 IS_BINOP_MATCHER(Float64InsertLowWord32)
2281 IS_BINOP_MATCHER(Float64InsertHighWord32)
2282 #undef IS_BINOP_MATCHER
2283 
2284 
2285 #define IS_UNOP_MATCHER(Name)                                                \
2286   Matcher<Node*> Is##Name(const Matcher<Node*>& input_matcher) {             \
2287     return MakeMatcher(new IsUnopMatcher(IrOpcode::k##Name, input_matcher)); \
2288   }
2289 IS_UNOP_MATCHER(BooleanNot)
2290 IS_UNOP_MATCHER(BitcastWordToTagged)
2291 IS_UNOP_MATCHER(TruncateFloat64ToWord32)
2292 IS_UNOP_MATCHER(ChangeFloat64ToInt32)
2293 IS_UNOP_MATCHER(ChangeFloat64ToUint32)
2294 IS_UNOP_MATCHER(ChangeInt32ToFloat64)
2295 IS_UNOP_MATCHER(ChangeInt32ToInt64)
2296 IS_UNOP_MATCHER(ChangeUint32ToFloat64)
2297 IS_UNOP_MATCHER(ChangeUint32ToUint64)
2298 IS_UNOP_MATCHER(TruncateFloat64ToFloat32)
2299 IS_UNOP_MATCHER(TruncateInt64ToInt32)
2300 IS_UNOP_MATCHER(Float32Abs)
2301 IS_UNOP_MATCHER(Float32Neg)
2302 IS_UNOP_MATCHER(Float64Abs)
2303 IS_UNOP_MATCHER(Float64Neg)
2304 IS_UNOP_MATCHER(Float64Sqrt)
2305 IS_UNOP_MATCHER(Float64RoundDown)
2306 IS_UNOP_MATCHER(Float64RoundTruncate)
2307 IS_UNOP_MATCHER(Float64RoundTiesAway)
2308 IS_UNOP_MATCHER(Float64ExtractLowWord32)
2309 IS_UNOP_MATCHER(Float64ExtractHighWord32)
2310 IS_UNOP_MATCHER(NumberAbs)
2311 IS_UNOP_MATCHER(NumberAcos)
2312 IS_UNOP_MATCHER(NumberAcosh)
2313 IS_UNOP_MATCHER(NumberAsin)
2314 IS_UNOP_MATCHER(NumberAsinh)
2315 IS_UNOP_MATCHER(NumberAtan)
2316 IS_UNOP_MATCHER(NumberAtanh)
2317 IS_UNOP_MATCHER(NumberCeil)
2318 IS_UNOP_MATCHER(NumberClz32)
2319 IS_UNOP_MATCHER(NumberCbrt)
2320 IS_UNOP_MATCHER(NumberCos)
2321 IS_UNOP_MATCHER(NumberCosh)
2322 IS_UNOP_MATCHER(NumberExp)
2323 IS_UNOP_MATCHER(NumberExpm1)
2324 IS_UNOP_MATCHER(NumberFloor)
2325 IS_UNOP_MATCHER(NumberFround)
2326 IS_UNOP_MATCHER(NumberLog)
2327 IS_UNOP_MATCHER(NumberLog1p)
2328 IS_UNOP_MATCHER(NumberLog10)
2329 IS_UNOP_MATCHER(NumberLog2)
2330 IS_UNOP_MATCHER(NumberRound)
2331 IS_UNOP_MATCHER(NumberSign)
2332 IS_UNOP_MATCHER(NumberSin)
2333 IS_UNOP_MATCHER(NumberSinh)
2334 IS_UNOP_MATCHER(NumberSqrt)
2335 IS_UNOP_MATCHER(NumberTan)
2336 IS_UNOP_MATCHER(NumberTanh)
2337 IS_UNOP_MATCHER(NumberTrunc)
2338 IS_UNOP_MATCHER(NumberToBoolean)
2339 IS_UNOP_MATCHER(NumberToInt32)
2340 IS_UNOP_MATCHER(NumberToUint32)
2341 IS_UNOP_MATCHER(PlainPrimitiveToNumber)
2342 IS_UNOP_MATCHER(ObjectIsFiniteNumber)
2343 IS_UNOP_MATCHER(NumberIsFinite)
2344 IS_UNOP_MATCHER(ObjectIsInteger)
2345 IS_UNOP_MATCHER(ObjectIsSafeInteger)
2346 IS_UNOP_MATCHER(ObjectIsNaN)
2347 IS_UNOP_MATCHER(NumberIsNaN)
2348 IS_UNOP_MATCHER(ObjectIsReceiver)
2349 IS_UNOP_MATCHER(ObjectIsSmi)
2350 IS_UNOP_MATCHER(ObjectIsUndetectable)
2351 IS_UNOP_MATCHER(StringFromSingleCharCode)
2352 IS_UNOP_MATCHER(StringLength)
2353 IS_UNOP_MATCHER(Word32Clz)
2354 IS_UNOP_MATCHER(Word32Ctz)
2355 IS_UNOP_MATCHER(Word32Popcnt)
2356 IS_UNOP_MATCHER(Word32ReverseBytes)
2357 IS_UNOP_MATCHER(SpeculativeToNumber)
2358 #undef IS_UNOP_MATCHER
2359 
2360 // Special-case Bitcast operators which are disabled when ENABLE_VERIFY_CSA is
2361 // not enabled.
2362 Matcher<Node*> IsBitcastTaggedToWord(const Matcher<Node*>& input_matcher) {
2363   return MakeMatcher(
2364       new IsUnopMatcher(IrOpcode::kBitcastTaggedToWord, input_matcher));
2365 }
2366 
IsBitcastWordToTaggedSigned(const Matcher<Node * > & input_matcher)2367 Matcher<Node*> IsBitcastWordToTaggedSigned(
2368     const Matcher<Node*>& input_matcher) {
2369   return MakeMatcher(
2370       new IsUnopMatcher(IrOpcode::kBitcastWordToTaggedSigned, input_matcher));
2371 }
2372 
2373 #undef LOAD_MATCHER
2374 #undef STORE_MATCHER
2375 #undef IS_QUADOP_MATCHER
2376 #undef IS_TERNOP_MATCHER
2377 
2378 }  // namespace compiler
2379 }  // namespace internal
2380 }  // namespace v8
2381