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