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.
5 #include "test/unittests/compiler/node-test-utils.h"
7 #include "src/compiler/node-properties-inl.h"
8 #include "src/compiler/simplified-operator.h"
11 using testing::MakeMatcher;
12 using testing::MatcherInterface;
13 using testing::MatchResultListener;
14 using testing::StringMatchResultListener;
23 bool PrintMatchAndExplain(const T& value, const char* value_name,
24 const Matcher<T>& value_matcher,
25 MatchResultListener* listener) {
26 StringMatchResultListener value_listener;
27 if (!value_matcher.MatchAndExplain(value, &value_listener)) {
28 *listener << "whose " << value_name << " " << value << " doesn't match";
29 if (value_listener.str() != "") {
30 *listener << ", " << value_listener.str();
38 class NodeMatcher : public MatcherInterface<Node*> {
40 explicit NodeMatcher(IrOpcode::Value opcode) : opcode_(opcode) {}
42 virtual void DescribeTo(std::ostream* os) const OVERRIDE {
43 *os << "is a " << IrOpcode::Mnemonic(opcode_) << " node";
46 virtual bool MatchAndExplain(Node* node,
47 MatchResultListener* listener) const OVERRIDE {
49 *listener << "which is NULL";
52 if (node->opcode() != opcode_) {
53 *listener << "whose opcode is " << IrOpcode::Mnemonic(node->opcode())
54 << " but should have been " << IrOpcode::Mnemonic(opcode_);
61 const IrOpcode::Value opcode_;
65 class IsBranchMatcher FINAL : public NodeMatcher {
67 IsBranchMatcher(const Matcher<Node*>& value_matcher,
68 const Matcher<Node*>& control_matcher)
69 : NodeMatcher(IrOpcode::kBranch),
70 value_matcher_(value_matcher),
71 control_matcher_(control_matcher) {}
73 virtual void DescribeTo(std::ostream* os) const OVERRIDE {
74 NodeMatcher::DescribeTo(os);
75 *os << " whose value (";
76 value_matcher_.DescribeTo(os);
77 *os << ") and control (";
78 control_matcher_.DescribeTo(os);
82 virtual bool MatchAndExplain(Node* node,
83 MatchResultListener* listener) const OVERRIDE {
84 return (NodeMatcher::MatchAndExplain(node, listener) &&
85 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
86 "value", value_matcher_, listener) &&
87 PrintMatchAndExplain(NodeProperties::GetControlInput(node),
88 "control", control_matcher_, listener));
92 const Matcher<Node*> value_matcher_;
93 const Matcher<Node*> control_matcher_;
97 class IsMergeMatcher FINAL : public NodeMatcher {
99 IsMergeMatcher(const Matcher<Node*>& control0_matcher,
100 const Matcher<Node*>& control1_matcher)
101 : NodeMatcher(IrOpcode::kMerge),
102 control0_matcher_(control0_matcher),
103 control1_matcher_(control1_matcher) {}
105 virtual void DescribeTo(std::ostream* os) const OVERRIDE {
106 NodeMatcher::DescribeTo(os);
107 *os << " whose control0 (";
108 control0_matcher_.DescribeTo(os);
109 *os << ") and control1 (";
110 control1_matcher_.DescribeTo(os);
114 virtual bool MatchAndExplain(Node* node,
115 MatchResultListener* listener) const OVERRIDE {
116 return (NodeMatcher::MatchAndExplain(node, listener) &&
117 PrintMatchAndExplain(NodeProperties::GetControlInput(node, 0),
118 "control0", control0_matcher_, listener) &&
119 PrintMatchAndExplain(NodeProperties::GetControlInput(node, 1),
120 "control1", control1_matcher_, listener));
124 const Matcher<Node*> control0_matcher_;
125 const Matcher<Node*> control1_matcher_;
129 class IsControl1Matcher FINAL : public NodeMatcher {
131 IsControl1Matcher(IrOpcode::Value opcode,
132 const Matcher<Node*>& control_matcher)
133 : NodeMatcher(opcode), control_matcher_(control_matcher) {}
135 virtual void DescribeTo(std::ostream* os) const OVERRIDE {
136 NodeMatcher::DescribeTo(os);
137 *os << " whose control (";
138 control_matcher_.DescribeTo(os);
142 virtual bool MatchAndExplain(Node* node,
143 MatchResultListener* listener) const OVERRIDE {
144 return (NodeMatcher::MatchAndExplain(node, listener) &&
145 PrintMatchAndExplain(NodeProperties::GetControlInput(node),
146 "control", control_matcher_, listener));
150 const Matcher<Node*> control_matcher_;
154 class IsFinishMatcher FINAL : public NodeMatcher {
156 IsFinishMatcher(const Matcher<Node*>& value_matcher,
157 const Matcher<Node*>& effect_matcher)
158 : NodeMatcher(IrOpcode::kFinish),
159 value_matcher_(value_matcher),
160 effect_matcher_(effect_matcher) {}
162 virtual void DescribeTo(std::ostream* os) const OVERRIDE {
163 NodeMatcher::DescribeTo(os);
164 *os << " whose value (";
165 value_matcher_.DescribeTo(os);
166 *os << ") and effect (";
167 effect_matcher_.DescribeTo(os);
171 virtual bool MatchAndExplain(Node* node,
172 MatchResultListener* listener) const OVERRIDE {
173 return (NodeMatcher::MatchAndExplain(node, listener) &&
174 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
175 "value", value_matcher_, listener) &&
176 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
177 effect_matcher_, listener));
181 const Matcher<Node*> value_matcher_;
182 const Matcher<Node*> effect_matcher_;
186 template <typename T>
187 class IsConstantMatcher FINAL : public NodeMatcher {
189 IsConstantMatcher(IrOpcode::Value opcode, const Matcher<T>& value_matcher)
190 : NodeMatcher(opcode), value_matcher_(value_matcher) {}
192 virtual void DescribeTo(std::ostream* os) const OVERRIDE {
193 NodeMatcher::DescribeTo(os);
194 *os << " whose value (";
195 value_matcher_.DescribeTo(os);
199 virtual bool MatchAndExplain(Node* node,
200 MatchResultListener* listener) const OVERRIDE {
201 return (NodeMatcher::MatchAndExplain(node, listener) &&
202 PrintMatchAndExplain(OpParameter<T>(node), "value", value_matcher_,
207 const Matcher<T> value_matcher_;
211 class IsSelectMatcher FINAL : public NodeMatcher {
213 IsSelectMatcher(const Matcher<MachineType>& type_matcher,
214 const Matcher<Node*>& value0_matcher,
215 const Matcher<Node*>& value1_matcher,
216 const Matcher<Node*>& value2_matcher)
217 : NodeMatcher(IrOpcode::kSelect),
218 type_matcher_(type_matcher),
219 value0_matcher_(value0_matcher),
220 value1_matcher_(value1_matcher),
221 value2_matcher_(value2_matcher) {}
223 virtual void DescribeTo(std::ostream* os) const OVERRIDE {
224 NodeMatcher::DescribeTo(os);
225 *os << " whose type (";
226 type_matcher_.DescribeTo(os);
227 *os << "), value0 (";
228 value0_matcher_.DescribeTo(os);
229 *os << "), value1 (";
230 value1_matcher_.DescribeTo(os);
231 *os << ") and value2 (";
232 value2_matcher_.DescribeTo(os);
236 virtual bool MatchAndExplain(Node* node,
237 MatchResultListener* listener) const OVERRIDE {
238 return (NodeMatcher::MatchAndExplain(node, listener) &&
239 PrintMatchAndExplain(OpParameter<MachineType>(node), "type",
240 type_matcher_, listener) &&
241 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
242 "value0", value0_matcher_, listener) &&
243 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
244 "value1", value1_matcher_, listener) &&
245 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2),
246 "value2", value2_matcher_, listener));
250 const Matcher<MachineType> type_matcher_;
251 const Matcher<Node*> value0_matcher_;
252 const Matcher<Node*> value1_matcher_;
253 const Matcher<Node*> value2_matcher_;
257 class IsPhiMatcher FINAL : public NodeMatcher {
259 IsPhiMatcher(const Matcher<MachineType>& type_matcher,
260 const Matcher<Node*>& value0_matcher,
261 const Matcher<Node*>& value1_matcher,
262 const Matcher<Node*>& control_matcher)
263 : NodeMatcher(IrOpcode::kPhi),
264 type_matcher_(type_matcher),
265 value0_matcher_(value0_matcher),
266 value1_matcher_(value1_matcher),
267 control_matcher_(control_matcher) {}
269 virtual void DescribeTo(std::ostream* os) const OVERRIDE {
270 NodeMatcher::DescribeTo(os);
271 *os << " whose type (";
272 type_matcher_.DescribeTo(os);
273 *os << "), value0 (";
274 value0_matcher_.DescribeTo(os);
275 *os << "), value1 (";
276 value1_matcher_.DescribeTo(os);
277 *os << ") and control (";
278 control_matcher_.DescribeTo(os);
282 virtual bool MatchAndExplain(Node* node,
283 MatchResultListener* listener) const OVERRIDE {
284 return (NodeMatcher::MatchAndExplain(node, listener) &&
285 PrintMatchAndExplain(OpParameter<MachineType>(node), "type",
286 type_matcher_, listener) &&
287 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
288 "value0", value0_matcher_, listener) &&
289 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
290 "value1", value1_matcher_, listener) &&
291 PrintMatchAndExplain(NodeProperties::GetControlInput(node),
292 "control", control_matcher_, listener));
296 const Matcher<MachineType> type_matcher_;
297 const Matcher<Node*> value0_matcher_;
298 const Matcher<Node*> value1_matcher_;
299 const Matcher<Node*> control_matcher_;
303 class IsEffectPhiMatcher FINAL : public NodeMatcher {
305 IsEffectPhiMatcher(const Matcher<Node*>& effect0_matcher,
306 const Matcher<Node*>& effect1_matcher,
307 const Matcher<Node*>& control_matcher)
308 : NodeMatcher(IrOpcode::kEffectPhi),
309 effect0_matcher_(effect0_matcher),
310 effect1_matcher_(effect1_matcher),
311 control_matcher_(control_matcher) {}
313 virtual void DescribeTo(std::ostream* os) const OVERRIDE {
314 NodeMatcher::DescribeTo(os);
315 *os << "), effect0 (";
316 effect0_matcher_.DescribeTo(os);
317 *os << "), effect1 (";
318 effect1_matcher_.DescribeTo(os);
319 *os << ") and control (";
320 control_matcher_.DescribeTo(os);
324 virtual bool MatchAndExplain(Node* node,
325 MatchResultListener* listener) const OVERRIDE {
326 return (NodeMatcher::MatchAndExplain(node, listener) &&
327 PrintMatchAndExplain(NodeProperties::GetEffectInput(node, 0),
328 "effect0", effect0_matcher_, listener) &&
329 PrintMatchAndExplain(NodeProperties::GetEffectInput(node, 1),
330 "effect1", effect1_matcher_, listener) &&
331 PrintMatchAndExplain(NodeProperties::GetControlInput(node),
332 "control", control_matcher_, listener));
336 const Matcher<Node*> effect0_matcher_;
337 const Matcher<Node*> effect1_matcher_;
338 const Matcher<Node*> control_matcher_;
342 class IsProjectionMatcher FINAL : public NodeMatcher {
344 IsProjectionMatcher(const Matcher<size_t>& index_matcher,
345 const Matcher<Node*>& base_matcher)
346 : NodeMatcher(IrOpcode::kProjection),
347 index_matcher_(index_matcher),
348 base_matcher_(base_matcher) {}
350 virtual void DescribeTo(std::ostream* os) const OVERRIDE {
351 NodeMatcher::DescribeTo(os);
352 *os << " whose index (";
353 index_matcher_.DescribeTo(os);
354 *os << ") and base (";
355 base_matcher_.DescribeTo(os);
359 virtual bool MatchAndExplain(Node* node,
360 MatchResultListener* listener) const OVERRIDE {
361 return (NodeMatcher::MatchAndExplain(node, listener) &&
362 PrintMatchAndExplain(OpParameter<size_t>(node), "index",
363 index_matcher_, listener) &&
364 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
365 base_matcher_, listener));
369 const Matcher<size_t> index_matcher_;
370 const Matcher<Node*> base_matcher_;
374 class IsCall2Matcher FINAL : public NodeMatcher {
376 IsCall2Matcher(const Matcher<CallDescriptor*>& descriptor_matcher,
377 const Matcher<Node*>& value0_matcher,
378 const Matcher<Node*>& value1_matcher,
379 const Matcher<Node*>& effect_matcher,
380 const Matcher<Node*>& control_matcher)
381 : NodeMatcher(IrOpcode::kCall),
382 descriptor_matcher_(descriptor_matcher),
383 value0_matcher_(value0_matcher),
384 value1_matcher_(value1_matcher),
385 effect_matcher_(effect_matcher),
386 control_matcher_(control_matcher) {}
388 virtual void DescribeTo(std::ostream* os) const OVERRIDE {
389 NodeMatcher::DescribeTo(os);
390 *os << " whose value0 (";
391 value0_matcher_.DescribeTo(os);
392 *os << ") and value1 (";
393 value1_matcher_.DescribeTo(os);
394 *os << ") and effect (";
395 effect_matcher_.DescribeTo(os);
396 *os << ") and control (";
397 control_matcher_.DescribeTo(os);
401 virtual bool MatchAndExplain(Node* node,
402 MatchResultListener* listener) const OVERRIDE {
403 return (NodeMatcher::MatchAndExplain(node, listener) &&
404 PrintMatchAndExplain(OpParameter<CallDescriptor*>(node),
405 "descriptor", descriptor_matcher_, listener) &&
406 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
407 "value0", value0_matcher_, listener) &&
408 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
409 "value1", value1_matcher_, listener) &&
410 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
411 effect_matcher_, listener) &&
412 PrintMatchAndExplain(NodeProperties::GetControlInput(node),
413 "control", control_matcher_, listener));
417 const Matcher<CallDescriptor*> descriptor_matcher_;
418 const Matcher<Node*> value0_matcher_;
419 const Matcher<Node*> value1_matcher_;
420 const Matcher<Node*> effect_matcher_;
421 const Matcher<Node*> control_matcher_;
425 class IsCall4Matcher FINAL : public NodeMatcher {
427 IsCall4Matcher(const Matcher<CallDescriptor*>& descriptor_matcher,
428 const Matcher<Node*>& value0_matcher,
429 const Matcher<Node*>& value1_matcher,
430 const Matcher<Node*>& value2_matcher,
431 const Matcher<Node*>& value3_matcher,
432 const Matcher<Node*>& effect_matcher,
433 const Matcher<Node*>& control_matcher)
434 : NodeMatcher(IrOpcode::kCall),
435 descriptor_matcher_(descriptor_matcher),
436 value0_matcher_(value0_matcher),
437 value1_matcher_(value1_matcher),
438 value2_matcher_(value2_matcher),
439 value3_matcher_(value3_matcher),
440 effect_matcher_(effect_matcher),
441 control_matcher_(control_matcher) {}
443 virtual void DescribeTo(std::ostream* os) const OVERRIDE {
444 NodeMatcher::DescribeTo(os);
445 *os << " whose value0 (";
446 value0_matcher_.DescribeTo(os);
447 *os << ") and value1 (";
448 value1_matcher_.DescribeTo(os);
449 *os << ") and value2 (";
450 value2_matcher_.DescribeTo(os);
451 *os << ") and value3 (";
452 value3_matcher_.DescribeTo(os);
453 *os << ") and effect (";
454 effect_matcher_.DescribeTo(os);
455 *os << ") and control (";
456 control_matcher_.DescribeTo(os);
460 virtual bool MatchAndExplain(Node* node,
461 MatchResultListener* listener) const OVERRIDE {
462 return (NodeMatcher::MatchAndExplain(node, listener) &&
463 PrintMatchAndExplain(OpParameter<CallDescriptor*>(node),
464 "descriptor", descriptor_matcher_, listener) &&
465 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
466 "value0", value0_matcher_, listener) &&
467 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
468 "value1", value1_matcher_, listener) &&
469 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2),
470 "value2", value2_matcher_, listener) &&
471 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 3),
472 "value3", value3_matcher_, listener) &&
473 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
474 effect_matcher_, listener) &&
475 PrintMatchAndExplain(NodeProperties::GetControlInput(node),
476 "control", control_matcher_, listener));
480 const Matcher<CallDescriptor*> descriptor_matcher_;
481 const Matcher<Node*> value0_matcher_;
482 const Matcher<Node*> value1_matcher_;
483 const Matcher<Node*> value2_matcher_;
484 const Matcher<Node*> value3_matcher_;
485 const Matcher<Node*> effect_matcher_;
486 const Matcher<Node*> control_matcher_;
490 class IsLoadFieldMatcher FINAL : public NodeMatcher {
492 IsLoadFieldMatcher(const Matcher<FieldAccess>& access_matcher,
493 const Matcher<Node*>& base_matcher,
494 const Matcher<Node*>& effect_matcher,
495 const Matcher<Node*>& control_matcher)
496 : NodeMatcher(IrOpcode::kLoadField),
497 access_matcher_(access_matcher),
498 base_matcher_(base_matcher),
499 effect_matcher_(effect_matcher),
500 control_matcher_(control_matcher) {}
502 virtual void DescribeTo(std::ostream* os) const OVERRIDE {
503 NodeMatcher::DescribeTo(os);
504 *os << " whose access (";
505 access_matcher_.DescribeTo(os);
507 base_matcher_.DescribeTo(os);
508 *os << "), effect (";
509 effect_matcher_.DescribeTo(os);
510 *os << ") and control (";
511 control_matcher_.DescribeTo(os);
515 virtual bool MatchAndExplain(Node* node,
516 MatchResultListener* listener) const OVERRIDE {
517 return (NodeMatcher::MatchAndExplain(node, listener) &&
518 PrintMatchAndExplain(OpParameter<FieldAccess>(node), "access",
519 access_matcher_, listener) &&
520 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
521 base_matcher_, listener) &&
522 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
523 effect_matcher_, listener) &&
524 PrintMatchAndExplain(NodeProperties::GetControlInput(node),
525 "control", control_matcher_, listener));
529 const Matcher<FieldAccess> access_matcher_;
530 const Matcher<Node*> base_matcher_;
531 const Matcher<Node*> effect_matcher_;
532 const Matcher<Node*> control_matcher_;
536 class IsLoadElementMatcher FINAL : public NodeMatcher {
538 IsLoadElementMatcher(const Matcher<ElementAccess>& access_matcher,
539 const Matcher<Node*>& base_matcher,
540 const Matcher<Node*>& index_matcher,
541 const Matcher<Node*>& length_matcher,
542 const Matcher<Node*>& effect_matcher)
543 : NodeMatcher(IrOpcode::kLoadElement),
544 access_matcher_(access_matcher),
545 base_matcher_(base_matcher),
546 index_matcher_(index_matcher),
547 length_matcher_(length_matcher),
548 effect_matcher_(effect_matcher) {}
550 virtual void DescribeTo(std::ostream* os) const OVERRIDE {
551 NodeMatcher::DescribeTo(os);
552 *os << " whose access (";
553 access_matcher_.DescribeTo(os);
555 base_matcher_.DescribeTo(os);
557 index_matcher_.DescribeTo(os);
558 *os << "), length (";
559 length_matcher_.DescribeTo(os);
560 *os << ") and effect (";
561 effect_matcher_.DescribeTo(os);
565 virtual bool MatchAndExplain(Node* node,
566 MatchResultListener* listener) const OVERRIDE {
567 return (NodeMatcher::MatchAndExplain(node, listener) &&
568 PrintMatchAndExplain(OpParameter<ElementAccess>(node), "access",
569 access_matcher_, listener) &&
570 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
571 base_matcher_, listener) &&
572 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
573 "index", index_matcher_, listener) &&
574 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2),
575 "length", length_matcher_, listener) &&
576 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
577 effect_matcher_, listener));
581 const Matcher<ElementAccess> access_matcher_;
582 const Matcher<Node*> base_matcher_;
583 const Matcher<Node*> index_matcher_;
584 const Matcher<Node*> length_matcher_;
585 const Matcher<Node*> effect_matcher_;
589 class IsStoreElementMatcher FINAL : public NodeMatcher {
591 IsStoreElementMatcher(const Matcher<ElementAccess>& access_matcher,
592 const Matcher<Node*>& base_matcher,
593 const Matcher<Node*>& index_matcher,
594 const Matcher<Node*>& length_matcher,
595 const Matcher<Node*>& value_matcher,
596 const Matcher<Node*>& effect_matcher,
597 const Matcher<Node*>& control_matcher)
598 : NodeMatcher(IrOpcode::kStoreElement),
599 access_matcher_(access_matcher),
600 base_matcher_(base_matcher),
601 index_matcher_(index_matcher),
602 length_matcher_(length_matcher),
603 value_matcher_(value_matcher),
604 effect_matcher_(effect_matcher),
605 control_matcher_(control_matcher) {}
607 virtual void DescribeTo(std::ostream* os) const OVERRIDE {
608 NodeMatcher::DescribeTo(os);
609 *os << " whose access (";
610 access_matcher_.DescribeTo(os);
612 base_matcher_.DescribeTo(os);
614 index_matcher_.DescribeTo(os);
615 *os << "), length (";
616 length_matcher_.DescribeTo(os);
618 value_matcher_.DescribeTo(os);
619 *os << "), effect (";
620 effect_matcher_.DescribeTo(os);
621 *os << ") and control (";
622 control_matcher_.DescribeTo(os);
626 virtual bool MatchAndExplain(Node* node,
627 MatchResultListener* listener) const OVERRIDE {
628 return (NodeMatcher::MatchAndExplain(node, listener) &&
629 PrintMatchAndExplain(OpParameter<ElementAccess>(node), "access",
630 access_matcher_, listener) &&
631 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
632 base_matcher_, listener) &&
633 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
634 "index", index_matcher_, listener) &&
635 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2),
636 "length", length_matcher_, listener) &&
637 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 3),
638 "value", value_matcher_, listener) &&
639 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
640 effect_matcher_, listener) &&
641 PrintMatchAndExplain(NodeProperties::GetControlInput(node),
642 "control", control_matcher_, listener));
646 const Matcher<ElementAccess> access_matcher_;
647 const Matcher<Node*> base_matcher_;
648 const Matcher<Node*> index_matcher_;
649 const Matcher<Node*> length_matcher_;
650 const Matcher<Node*> value_matcher_;
651 const Matcher<Node*> effect_matcher_;
652 const Matcher<Node*> control_matcher_;
656 class IsLoadMatcher FINAL : public NodeMatcher {
658 IsLoadMatcher(const Matcher<LoadRepresentation>& rep_matcher,
659 const Matcher<Node*>& base_matcher,
660 const Matcher<Node*>& index_matcher,
661 const Matcher<Node*>& effect_matcher,
662 const Matcher<Node*>& control_matcher)
663 : NodeMatcher(IrOpcode::kLoad),
664 rep_matcher_(rep_matcher),
665 base_matcher_(base_matcher),
666 index_matcher_(index_matcher),
667 effect_matcher_(effect_matcher),
668 control_matcher_(control_matcher) {}
670 virtual void DescribeTo(std::ostream* os) const OVERRIDE {
671 NodeMatcher::DescribeTo(os);
672 *os << " whose rep (";
673 rep_matcher_.DescribeTo(os);
675 base_matcher_.DescribeTo(os);
677 index_matcher_.DescribeTo(os);
678 *os << "), effect (";
679 effect_matcher_.DescribeTo(os);
680 *os << ") and control (";
681 control_matcher_.DescribeTo(os);
685 virtual bool MatchAndExplain(Node* node,
686 MatchResultListener* listener) const OVERRIDE {
687 return (NodeMatcher::MatchAndExplain(node, listener) &&
688 PrintMatchAndExplain(OpParameter<LoadRepresentation>(node), "rep",
689 rep_matcher_, listener) &&
690 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
691 base_matcher_, listener) &&
692 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
693 "index", index_matcher_, listener) &&
694 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
695 effect_matcher_, listener) &&
696 PrintMatchAndExplain(NodeProperties::GetControlInput(node),
697 "control", control_matcher_, listener));
701 const Matcher<LoadRepresentation> rep_matcher_;
702 const Matcher<Node*> base_matcher_;
703 const Matcher<Node*> index_matcher_;
704 const Matcher<Node*> effect_matcher_;
705 const Matcher<Node*> control_matcher_;
709 class IsStoreMatcher FINAL : public NodeMatcher {
711 IsStoreMatcher(const Matcher<StoreRepresentation>& rep_matcher,
712 const Matcher<Node*>& base_matcher,
713 const Matcher<Node*>& index_matcher,
714 const Matcher<Node*>& value_matcher,
715 const Matcher<Node*>& effect_matcher,
716 const Matcher<Node*>& control_matcher)
717 : NodeMatcher(IrOpcode::kStore),
718 rep_matcher_(rep_matcher),
719 base_matcher_(base_matcher),
720 index_matcher_(index_matcher),
721 value_matcher_(value_matcher),
722 effect_matcher_(effect_matcher),
723 control_matcher_(control_matcher) {}
725 virtual void DescribeTo(std::ostream* os) const OVERRIDE {
726 NodeMatcher::DescribeTo(os);
727 *os << " whose rep (";
728 rep_matcher_.DescribeTo(os);
730 base_matcher_.DescribeTo(os);
732 index_matcher_.DescribeTo(os);
734 value_matcher_.DescribeTo(os);
735 *os << "), effect (";
736 effect_matcher_.DescribeTo(os);
737 *os << ") and control (";
738 control_matcher_.DescribeTo(os);
742 virtual bool MatchAndExplain(Node* node,
743 MatchResultListener* listener) const OVERRIDE {
744 return (NodeMatcher::MatchAndExplain(node, listener) &&
745 PrintMatchAndExplain(OpParameter<StoreRepresentation>(node), "rep",
746 rep_matcher_, listener) &&
747 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
748 base_matcher_, listener) &&
749 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
750 "index", index_matcher_, listener) &&
751 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2),
752 "value", value_matcher_, listener) &&
753 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
754 effect_matcher_, listener) &&
755 PrintMatchAndExplain(NodeProperties::GetControlInput(node),
756 "control", control_matcher_, listener));
760 const Matcher<StoreRepresentation> rep_matcher_;
761 const Matcher<Node*> base_matcher_;
762 const Matcher<Node*> index_matcher_;
763 const Matcher<Node*> value_matcher_;
764 const Matcher<Node*> effect_matcher_;
765 const Matcher<Node*> control_matcher_;
769 class IsBinopMatcher FINAL : public NodeMatcher {
771 IsBinopMatcher(IrOpcode::Value opcode, const Matcher<Node*>& lhs_matcher,
772 const Matcher<Node*>& rhs_matcher)
773 : NodeMatcher(opcode),
774 lhs_matcher_(lhs_matcher),
775 rhs_matcher_(rhs_matcher) {}
777 virtual void DescribeTo(std::ostream* os) const OVERRIDE {
778 NodeMatcher::DescribeTo(os);
779 *os << " whose lhs (";
780 lhs_matcher_.DescribeTo(os);
781 *os << ") and rhs (";
782 rhs_matcher_.DescribeTo(os);
786 virtual bool MatchAndExplain(Node* node,
787 MatchResultListener* listener) const OVERRIDE {
788 return (NodeMatcher::MatchAndExplain(node, listener) &&
789 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "lhs",
790 lhs_matcher_, listener) &&
791 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "rhs",
792 rhs_matcher_, listener));
796 const Matcher<Node*> lhs_matcher_;
797 const Matcher<Node*> rhs_matcher_;
801 class IsUnopMatcher FINAL : public NodeMatcher {
803 IsUnopMatcher(IrOpcode::Value opcode, const Matcher<Node*>& input_matcher)
804 : NodeMatcher(opcode), input_matcher_(input_matcher) {}
806 virtual void DescribeTo(std::ostream* os) const OVERRIDE {
807 NodeMatcher::DescribeTo(os);
808 *os << " whose input (";
809 input_matcher_.DescribeTo(os);
813 virtual bool MatchAndExplain(Node* node,
814 MatchResultListener* listener) const OVERRIDE {
815 return (NodeMatcher::MatchAndExplain(node, listener) &&
816 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
817 "input", input_matcher_, listener));
821 const Matcher<Node*> input_matcher_;
826 Matcher<Node*> IsBranch(const Matcher<Node*>& value_matcher,
827 const Matcher<Node*>& control_matcher) {
828 return MakeMatcher(new IsBranchMatcher(value_matcher, control_matcher));
832 Matcher<Node*> IsMerge(const Matcher<Node*>& control0_matcher,
833 const Matcher<Node*>& control1_matcher) {
834 return MakeMatcher(new IsMergeMatcher(control0_matcher, control1_matcher));
838 Matcher<Node*> IsIfTrue(const Matcher<Node*>& control_matcher) {
839 return MakeMatcher(new IsControl1Matcher(IrOpcode::kIfTrue, control_matcher));
843 Matcher<Node*> IsIfFalse(const Matcher<Node*>& control_matcher) {
845 new IsControl1Matcher(IrOpcode::kIfFalse, control_matcher));
849 Matcher<Node*> IsValueEffect(const Matcher<Node*>& value_matcher) {
850 return MakeMatcher(new IsUnopMatcher(IrOpcode::kValueEffect, value_matcher));
854 Matcher<Node*> IsFinish(const Matcher<Node*>& value_matcher,
855 const Matcher<Node*>& effect_matcher) {
856 return MakeMatcher(new IsFinishMatcher(value_matcher, effect_matcher));
860 Matcher<Node*> IsExternalConstant(
861 const Matcher<ExternalReference>& value_matcher) {
862 return MakeMatcher(new IsConstantMatcher<ExternalReference>(
863 IrOpcode::kExternalConstant, value_matcher));
867 Matcher<Node*> IsHeapConstant(
868 const Matcher<Unique<HeapObject> >& value_matcher) {
869 return MakeMatcher(new IsConstantMatcher<Unique<HeapObject> >(
870 IrOpcode::kHeapConstant, value_matcher));
874 Matcher<Node*> IsInt32Constant(const Matcher<int32_t>& value_matcher) {
876 new IsConstantMatcher<int32_t>(IrOpcode::kInt32Constant, value_matcher));
880 Matcher<Node*> IsInt64Constant(const Matcher<int64_t>& value_matcher) {
882 new IsConstantMatcher<int64_t>(IrOpcode::kInt64Constant, value_matcher));
886 Matcher<Node*> IsFloat32Constant(const Matcher<float>& value_matcher) {
888 new IsConstantMatcher<float>(IrOpcode::kFloat32Constant, value_matcher));
892 Matcher<Node*> IsFloat64Constant(const Matcher<double>& value_matcher) {
894 new IsConstantMatcher<double>(IrOpcode::kFloat64Constant, value_matcher));
898 Matcher<Node*> IsNumberConstant(const Matcher<double>& value_matcher) {
900 new IsConstantMatcher<double>(IrOpcode::kNumberConstant, value_matcher));
904 Matcher<Node*> IsSelect(const Matcher<MachineType>& type_matcher,
905 const Matcher<Node*>& value0_matcher,
906 const Matcher<Node*>& value1_matcher,
907 const Matcher<Node*>& value2_matcher) {
908 return MakeMatcher(new IsSelectMatcher(type_matcher, value0_matcher,
909 value1_matcher, value2_matcher));
913 Matcher<Node*> IsPhi(const Matcher<MachineType>& type_matcher,
914 const Matcher<Node*>& value0_matcher,
915 const Matcher<Node*>& value1_matcher,
916 const Matcher<Node*>& merge_matcher) {
917 return MakeMatcher(new IsPhiMatcher(type_matcher, value0_matcher,
918 value1_matcher, merge_matcher));
922 Matcher<Node*> IsEffectPhi(const Matcher<Node*>& effect0_matcher,
923 const Matcher<Node*>& effect1_matcher,
924 const Matcher<Node*>& merge_matcher) {
926 new IsEffectPhiMatcher(effect0_matcher, effect1_matcher, merge_matcher));
930 Matcher<Node*> IsProjection(const Matcher<size_t>& index_matcher,
931 const Matcher<Node*>& base_matcher) {
932 return MakeMatcher(new IsProjectionMatcher(index_matcher, base_matcher));
936 Matcher<Node*> IsCall(const Matcher<CallDescriptor*>& descriptor_matcher,
937 const Matcher<Node*>& value0_matcher,
938 const Matcher<Node*>& value1_matcher,
939 const Matcher<Node*>& effect_matcher,
940 const Matcher<Node*>& control_matcher) {
941 return MakeMatcher(new IsCall2Matcher(descriptor_matcher, value0_matcher,
942 value1_matcher, effect_matcher,
947 Matcher<Node*> IsCall(const Matcher<CallDescriptor*>& descriptor_matcher,
948 const Matcher<Node*>& value0_matcher,
949 const Matcher<Node*>& value1_matcher,
950 const Matcher<Node*>& value2_matcher,
951 const Matcher<Node*>& value3_matcher,
952 const Matcher<Node*>& effect_matcher,
953 const Matcher<Node*>& control_matcher) {
954 return MakeMatcher(new IsCall4Matcher(
955 descriptor_matcher, value0_matcher, value1_matcher, value2_matcher,
956 value3_matcher, effect_matcher, control_matcher));
960 Matcher<Node*> IsLoadField(const Matcher<FieldAccess>& access_matcher,
961 const Matcher<Node*>& base_matcher,
962 const Matcher<Node*>& effect_matcher,
963 const Matcher<Node*>& control_matcher) {
964 return MakeMatcher(new IsLoadFieldMatcher(access_matcher, base_matcher,
965 effect_matcher, control_matcher));
969 Matcher<Node*> IsLoadElement(const Matcher<ElementAccess>& access_matcher,
970 const Matcher<Node*>& base_matcher,
971 const Matcher<Node*>& index_matcher,
972 const Matcher<Node*>& length_matcher,
973 const Matcher<Node*>& effect_matcher) {
974 return MakeMatcher(new IsLoadElementMatcher(access_matcher, base_matcher,
975 index_matcher, length_matcher,
980 Matcher<Node*> IsStoreElement(const Matcher<ElementAccess>& access_matcher,
981 const Matcher<Node*>& base_matcher,
982 const Matcher<Node*>& index_matcher,
983 const Matcher<Node*>& length_matcher,
984 const Matcher<Node*>& value_matcher,
985 const Matcher<Node*>& effect_matcher,
986 const Matcher<Node*>& control_matcher) {
987 return MakeMatcher(new IsStoreElementMatcher(
988 access_matcher, base_matcher, index_matcher, length_matcher,
989 value_matcher, effect_matcher, control_matcher));
993 Matcher<Node*> IsLoad(const Matcher<LoadRepresentation>& rep_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 return MakeMatcher(new IsLoadMatcher(rep_matcher, base_matcher, index_matcher,
999 effect_matcher, control_matcher));
1003 Matcher<Node*> IsStore(const Matcher<StoreRepresentation>& rep_matcher,
1004 const Matcher<Node*>& base_matcher,
1005 const Matcher<Node*>& index_matcher,
1006 const Matcher<Node*>& value_matcher,
1007 const Matcher<Node*>& effect_matcher,
1008 const Matcher<Node*>& control_matcher) {
1009 return MakeMatcher(new IsStoreMatcher(rep_matcher, base_matcher,
1010 index_matcher, value_matcher,
1011 effect_matcher, control_matcher));
1015 #define IS_BINOP_MATCHER(Name) \
1016 Matcher<Node*> Is##Name(const Matcher<Node*>& lhs_matcher, \
1017 const Matcher<Node*>& rhs_matcher) { \
1018 return MakeMatcher( \
1019 new IsBinopMatcher(IrOpcode::k##Name, lhs_matcher, rhs_matcher)); \
1021 IS_BINOP_MATCHER(NumberEqual)
1022 IS_BINOP_MATCHER(NumberLessThan)
1023 IS_BINOP_MATCHER(NumberSubtract)
1024 IS_BINOP_MATCHER(NumberMultiply)
1025 IS_BINOP_MATCHER(Word32And)
1026 IS_BINOP_MATCHER(Word32Sar)
1027 IS_BINOP_MATCHER(Word32Shl)
1028 IS_BINOP_MATCHER(Word32Shr)
1029 IS_BINOP_MATCHER(Word32Ror)
1030 IS_BINOP_MATCHER(Word32Equal)
1031 IS_BINOP_MATCHER(Word64And)
1032 IS_BINOP_MATCHER(Word64Sar)
1033 IS_BINOP_MATCHER(Word64Shl)
1034 IS_BINOP_MATCHER(Word64Equal)
1035 IS_BINOP_MATCHER(Int32AddWithOverflow)
1036 IS_BINOP_MATCHER(Int32Add)
1037 IS_BINOP_MATCHER(Int32Sub)
1038 IS_BINOP_MATCHER(Int32Mul)
1039 IS_BINOP_MATCHER(Int32MulHigh)
1040 IS_BINOP_MATCHER(Int32LessThan)
1041 IS_BINOP_MATCHER(Uint32LessThan)
1042 IS_BINOP_MATCHER(Uint32LessThanOrEqual)
1043 #undef IS_BINOP_MATCHER
1046 #define IS_UNOP_MATCHER(Name) \
1047 Matcher<Node*> Is##Name(const Matcher<Node*>& input_matcher) { \
1048 return MakeMatcher(new IsUnopMatcher(IrOpcode::k##Name, input_matcher)); \
1050 IS_UNOP_MATCHER(BooleanNot)
1051 IS_UNOP_MATCHER(ChangeFloat64ToInt32)
1052 IS_UNOP_MATCHER(ChangeFloat64ToUint32)
1053 IS_UNOP_MATCHER(ChangeInt32ToFloat64)
1054 IS_UNOP_MATCHER(ChangeInt32ToInt64)
1055 IS_UNOP_MATCHER(ChangeUint32ToFloat64)
1056 IS_UNOP_MATCHER(ChangeUint32ToUint64)
1057 IS_UNOP_MATCHER(TruncateFloat64ToFloat32)
1058 IS_UNOP_MATCHER(TruncateFloat64ToInt32)
1059 IS_UNOP_MATCHER(TruncateInt64ToInt32)
1060 IS_UNOP_MATCHER(Float64Sqrt)
1061 IS_UNOP_MATCHER(Float64Floor)
1062 IS_UNOP_MATCHER(Float64Ceil)
1063 IS_UNOP_MATCHER(Float64RoundTruncate)
1064 IS_UNOP_MATCHER(Float64RoundTiesAway)
1065 #undef IS_UNOP_MATCHER
1067 } // namespace compiler
1068 } // namespace internal