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 "src/compiler/graph-unittest.h"
6
7#include <ostream>  // NOLINT(readability/streams)
8
9#include "src/compiler/node-properties-inl.h"
10
11using testing::_;
12using testing::MakeMatcher;
13using testing::MatcherInterface;
14using testing::MatchResultListener;
15using testing::StringMatchResultListener;
16
17namespace v8 {
18namespace internal {
19
20// TODO(bmeurer): Find a new home for these functions.
21template <typename T>
22inline std::ostream& operator<<(std::ostream& os, const Unique<T>& value) {
23  return os << *value.handle();
24}
25inline std::ostream& operator<<(std::ostream& os,
26                                const ExternalReference& value) {
27  OStringStream ost;
28  compiler::StaticParameterTraits<ExternalReference>::PrintTo(ost, value);
29  return os << ost.c_str();
30}
31
32namespace compiler {
33
34GraphTest::GraphTest(int num_parameters) : common_(zone()), graph_(zone()) {
35  graph()->SetStart(graph()->NewNode(common()->Start(num_parameters)));
36}
37
38
39GraphTest::~GraphTest() {}
40
41
42Node* GraphTest::Parameter(int32_t index) {
43  return graph()->NewNode(common()->Parameter(index), graph()->start());
44}
45
46
47Node* GraphTest::Float32Constant(volatile float value) {
48  return graph()->NewNode(common()->Float32Constant(value));
49}
50
51
52Node* GraphTest::Float64Constant(volatile double value) {
53  return graph()->NewNode(common()->Float64Constant(value));
54}
55
56
57Node* GraphTest::Int32Constant(int32_t value) {
58  return graph()->NewNode(common()->Int32Constant(value));
59}
60
61
62Node* GraphTest::Int64Constant(int64_t value) {
63  return graph()->NewNode(common()->Int64Constant(value));
64}
65
66
67Node* GraphTest::NumberConstant(volatile double value) {
68  return graph()->NewNode(common()->NumberConstant(value));
69}
70
71
72Node* GraphTest::HeapConstant(const Unique<HeapObject>& value) {
73  return graph()->NewNode(common()->HeapConstant(value));
74}
75
76
77Node* GraphTest::FalseConstant() {
78  return HeapConstant(
79      Unique<HeapObject>::CreateImmovable(factory()->false_value()));
80}
81
82
83Node* GraphTest::TrueConstant() {
84  return HeapConstant(
85      Unique<HeapObject>::CreateImmovable(factory()->true_value()));
86}
87
88
89Matcher<Node*> GraphTest::IsFalseConstant() {
90  return IsHeapConstant(
91      Unique<HeapObject>::CreateImmovable(factory()->false_value()));
92}
93
94
95Matcher<Node*> GraphTest::IsTrueConstant() {
96  return IsHeapConstant(
97      Unique<HeapObject>::CreateImmovable(factory()->true_value()));
98}
99
100namespace {
101
102template <typename T>
103bool PrintMatchAndExplain(const T& value, const char* value_name,
104                          const Matcher<T>& value_matcher,
105                          MatchResultListener* listener) {
106  StringMatchResultListener value_listener;
107  if (!value_matcher.MatchAndExplain(value, &value_listener)) {
108    *listener << "whose " << value_name << " " << value << " doesn't match";
109    if (value_listener.str() != "") {
110      *listener << ", " << value_listener.str();
111    }
112    return false;
113  }
114  return true;
115}
116
117
118class NodeMatcher : public MatcherInterface<Node*> {
119 public:
120  explicit NodeMatcher(IrOpcode::Value opcode) : opcode_(opcode) {}
121
122  virtual void DescribeTo(std::ostream* os) const OVERRIDE {
123    *os << "is a " << IrOpcode::Mnemonic(opcode_) << " node";
124  }
125
126  virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
127      OVERRIDE {
128    if (node == NULL) {
129      *listener << "which is NULL";
130      return false;
131    }
132    if (node->opcode() != opcode_) {
133      *listener << "whose opcode is " << IrOpcode::Mnemonic(node->opcode())
134                << " but should have been " << IrOpcode::Mnemonic(opcode_);
135      return false;
136    }
137    return true;
138  }
139
140 private:
141  const IrOpcode::Value opcode_;
142};
143
144
145class IsBranchMatcher FINAL : public NodeMatcher {
146 public:
147  IsBranchMatcher(const Matcher<Node*>& value_matcher,
148                  const Matcher<Node*>& control_matcher)
149      : NodeMatcher(IrOpcode::kBranch),
150        value_matcher_(value_matcher),
151        control_matcher_(control_matcher) {}
152
153  virtual void DescribeTo(std::ostream* os) const OVERRIDE {
154    NodeMatcher::DescribeTo(os);
155    *os << " whose value (";
156    value_matcher_.DescribeTo(os);
157    *os << ") and control (";
158    control_matcher_.DescribeTo(os);
159    *os << ")";
160  }
161
162  virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
163      OVERRIDE {
164    return (NodeMatcher::MatchAndExplain(node, listener) &&
165            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
166                                 "value", value_matcher_, listener) &&
167            PrintMatchAndExplain(NodeProperties::GetControlInput(node),
168                                 "control", control_matcher_, listener));
169  }
170
171 private:
172  const Matcher<Node*> value_matcher_;
173  const Matcher<Node*> control_matcher_;
174};
175
176
177class IsMergeMatcher FINAL : public NodeMatcher {
178 public:
179  IsMergeMatcher(const Matcher<Node*>& control0_matcher,
180                 const Matcher<Node*>& control1_matcher)
181      : NodeMatcher(IrOpcode::kMerge),
182        control0_matcher_(control0_matcher),
183        control1_matcher_(control1_matcher) {}
184
185  virtual void DescribeTo(std::ostream* os) const OVERRIDE {
186    NodeMatcher::DescribeTo(os);
187    *os << " whose control0 (";
188    control0_matcher_.DescribeTo(os);
189    *os << ") and control1 (";
190    control1_matcher_.DescribeTo(os);
191    *os << ")";
192  }
193
194  virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
195      OVERRIDE {
196    return (NodeMatcher::MatchAndExplain(node, listener) &&
197            PrintMatchAndExplain(NodeProperties::GetControlInput(node, 0),
198                                 "control0", control0_matcher_, listener) &&
199            PrintMatchAndExplain(NodeProperties::GetControlInput(node, 1),
200                                 "control1", control1_matcher_, listener));
201  }
202
203 private:
204  const Matcher<Node*> control0_matcher_;
205  const Matcher<Node*> control1_matcher_;
206};
207
208
209class IsControl1Matcher FINAL : public NodeMatcher {
210 public:
211  IsControl1Matcher(IrOpcode::Value opcode,
212                    const Matcher<Node*>& control_matcher)
213      : NodeMatcher(opcode), control_matcher_(control_matcher) {}
214
215  virtual void DescribeTo(std::ostream* os) const OVERRIDE {
216    NodeMatcher::DescribeTo(os);
217    *os << " whose control (";
218    control_matcher_.DescribeTo(os);
219    *os << ")";
220  }
221
222  virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
223      OVERRIDE {
224    return (NodeMatcher::MatchAndExplain(node, listener) &&
225            PrintMatchAndExplain(NodeProperties::GetControlInput(node),
226                                 "control", control_matcher_, listener));
227  }
228
229 private:
230  const Matcher<Node*> control_matcher_;
231};
232
233
234class IsFinishMatcher FINAL : public NodeMatcher {
235 public:
236  IsFinishMatcher(const Matcher<Node*>& value_matcher,
237                  const Matcher<Node*>& effect_matcher)
238      : NodeMatcher(IrOpcode::kFinish),
239        value_matcher_(value_matcher),
240        effect_matcher_(effect_matcher) {}
241
242  virtual void DescribeTo(std::ostream* os) const OVERRIDE {
243    NodeMatcher::DescribeTo(os);
244    *os << " whose value (";
245    value_matcher_.DescribeTo(os);
246    *os << ") and effect (";
247    effect_matcher_.DescribeTo(os);
248    *os << ")";
249  }
250
251  virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
252      OVERRIDE {
253    return (NodeMatcher::MatchAndExplain(node, listener) &&
254            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
255                                 "value", value_matcher_, listener) &&
256            PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
257                                 effect_matcher_, listener));
258  }
259
260 private:
261  const Matcher<Node*> value_matcher_;
262  const Matcher<Node*> effect_matcher_;
263};
264
265
266template <typename T>
267class IsConstantMatcher FINAL : public NodeMatcher {
268 public:
269  IsConstantMatcher(IrOpcode::Value opcode, const Matcher<T>& value_matcher)
270      : NodeMatcher(opcode), value_matcher_(value_matcher) {}
271
272  virtual void DescribeTo(std::ostream* os) const OVERRIDE {
273    NodeMatcher::DescribeTo(os);
274    *os << " whose value (";
275    value_matcher_.DescribeTo(os);
276    *os << ")";
277  }
278
279  virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
280      OVERRIDE {
281    return (NodeMatcher::MatchAndExplain(node, listener) &&
282            PrintMatchAndExplain(OpParameter<T>(node), "value", value_matcher_,
283                                 listener));
284  }
285
286 private:
287  const Matcher<T> value_matcher_;
288};
289
290
291class IsPhiMatcher FINAL : public NodeMatcher {
292 public:
293  IsPhiMatcher(const Matcher<MachineType>& type_matcher,
294               const Matcher<Node*>& value0_matcher,
295               const Matcher<Node*>& value1_matcher,
296               const Matcher<Node*>& control_matcher)
297      : NodeMatcher(IrOpcode::kPhi),
298        type_matcher_(type_matcher),
299        value0_matcher_(value0_matcher),
300        value1_matcher_(value1_matcher),
301        control_matcher_(control_matcher) {}
302
303  virtual void DescribeTo(std::ostream* os) const OVERRIDE {
304    NodeMatcher::DescribeTo(os);
305    *os << " whose type (";
306    type_matcher_.DescribeTo(os);
307    *os << "), value0 (";
308    value0_matcher_.DescribeTo(os);
309    *os << "), value1 (";
310    value1_matcher_.DescribeTo(os);
311    *os << ") and control (";
312    control_matcher_.DescribeTo(os);
313    *os << ")";
314  }
315
316  virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
317      OVERRIDE {
318    return (NodeMatcher::MatchAndExplain(node, listener) &&
319            PrintMatchAndExplain(OpParameter<MachineType>(node), "type",
320                                 type_matcher_, listener) &&
321            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
322                                 "value0", value0_matcher_, listener) &&
323            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
324                                 "value1", value1_matcher_, listener) &&
325            PrintMatchAndExplain(NodeProperties::GetControlInput(node),
326                                 "control", control_matcher_, listener));
327  }
328
329 private:
330  const Matcher<MachineType> type_matcher_;
331  const Matcher<Node*> value0_matcher_;
332  const Matcher<Node*> value1_matcher_;
333  const Matcher<Node*> control_matcher_;
334};
335
336
337class IsProjectionMatcher FINAL : public NodeMatcher {
338 public:
339  IsProjectionMatcher(const Matcher<size_t>& index_matcher,
340                      const Matcher<Node*>& base_matcher)
341      : NodeMatcher(IrOpcode::kProjection),
342        index_matcher_(index_matcher),
343        base_matcher_(base_matcher) {}
344
345  virtual void DescribeTo(std::ostream* os) const OVERRIDE {
346    NodeMatcher::DescribeTo(os);
347    *os << " whose index (";
348    index_matcher_.DescribeTo(os);
349    *os << ") and base (";
350    base_matcher_.DescribeTo(os);
351    *os << ")";
352  }
353
354  virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
355      OVERRIDE {
356    return (NodeMatcher::MatchAndExplain(node, listener) &&
357            PrintMatchAndExplain(OpParameter<size_t>(node), "index",
358                                 index_matcher_, listener) &&
359            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
360                                 base_matcher_, listener));
361  }
362
363 private:
364  const Matcher<size_t> index_matcher_;
365  const Matcher<Node*> base_matcher_;
366};
367
368
369class IsCallMatcher FINAL : public NodeMatcher {
370 public:
371  IsCallMatcher(const Matcher<CallDescriptor*>& descriptor_matcher,
372                const Matcher<Node*>& value0_matcher,
373                const Matcher<Node*>& value1_matcher,
374                const Matcher<Node*>& value2_matcher,
375                const Matcher<Node*>& value3_matcher,
376                const Matcher<Node*>& effect_matcher,
377                const Matcher<Node*>& control_matcher)
378      : NodeMatcher(IrOpcode::kCall),
379        descriptor_matcher_(descriptor_matcher),
380        value0_matcher_(value0_matcher),
381        value1_matcher_(value1_matcher),
382        value2_matcher_(value2_matcher),
383        value3_matcher_(value3_matcher),
384        effect_matcher_(effect_matcher),
385        control_matcher_(control_matcher) {}
386
387  virtual void DescribeTo(std::ostream* os) const OVERRIDE {
388    NodeMatcher::DescribeTo(os);
389    *os << " whose value0 (";
390    value0_matcher_.DescribeTo(os);
391    *os << ") and value1 (";
392    value1_matcher_.DescribeTo(os);
393    *os << ") and value2 (";
394    value2_matcher_.DescribeTo(os);
395    *os << ") and value3 (";
396    value3_matcher_.DescribeTo(os);
397    *os << ") and effect (";
398    effect_matcher_.DescribeTo(os);
399    *os << ") and control (";
400    control_matcher_.DescribeTo(os);
401    *os << ")";
402  }
403
404  virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
405      OVERRIDE {
406    return (NodeMatcher::MatchAndExplain(node, listener) &&
407            PrintMatchAndExplain(OpParameter<CallDescriptor*>(node),
408                                 "descriptor", descriptor_matcher_, listener) &&
409            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
410                                 "value0", value0_matcher_, listener) &&
411            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
412                                 "value1", value1_matcher_, listener) &&
413            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2),
414                                 "value2", value2_matcher_, listener) &&
415            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 3),
416                                 "value3", value3_matcher_, listener) &&
417            PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
418                                 effect_matcher_, listener) &&
419            PrintMatchAndExplain(NodeProperties::GetControlInput(node),
420                                 "control", control_matcher_, listener));
421  }
422
423 private:
424  const Matcher<CallDescriptor*> descriptor_matcher_;
425  const Matcher<Node*> value0_matcher_;
426  const Matcher<Node*> value1_matcher_;
427  const Matcher<Node*> value2_matcher_;
428  const Matcher<Node*> value3_matcher_;
429  const Matcher<Node*> effect_matcher_;
430  const Matcher<Node*> control_matcher_;
431};
432
433
434class IsLoadMatcher FINAL : public NodeMatcher {
435 public:
436  IsLoadMatcher(const Matcher<LoadRepresentation>& rep_matcher,
437                const Matcher<Node*>& base_matcher,
438                const Matcher<Node*>& index_matcher,
439                const Matcher<Node*>& effect_matcher)
440      : NodeMatcher(IrOpcode::kLoad),
441        rep_matcher_(rep_matcher),
442        base_matcher_(base_matcher),
443        index_matcher_(index_matcher),
444        effect_matcher_(effect_matcher) {}
445
446  virtual void DescribeTo(std::ostream* os) const OVERRIDE {
447    NodeMatcher::DescribeTo(os);
448    *os << " whose rep (";
449    rep_matcher_.DescribeTo(os);
450    *os << "), base (";
451    base_matcher_.DescribeTo(os);
452    *os << "), index (";
453    index_matcher_.DescribeTo(os);
454    *os << ") and effect (";
455    effect_matcher_.DescribeTo(os);
456    *os << ")";
457  }
458
459  virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
460      OVERRIDE {
461    return (NodeMatcher::MatchAndExplain(node, listener) &&
462            PrintMatchAndExplain(OpParameter<LoadRepresentation>(node), "rep",
463                                 rep_matcher_, listener) &&
464            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
465                                 base_matcher_, listener) &&
466            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
467                                 "index", index_matcher_, listener) &&
468            PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
469                                 effect_matcher_, listener));
470  }
471
472 private:
473  const Matcher<LoadRepresentation> rep_matcher_;
474  const Matcher<Node*> base_matcher_;
475  const Matcher<Node*> index_matcher_;
476  const Matcher<Node*> effect_matcher_;
477};
478
479
480class IsStoreMatcher FINAL : public NodeMatcher {
481 public:
482  IsStoreMatcher(const Matcher<MachineType>& type_matcher,
483                 const Matcher<WriteBarrierKind> write_barrier_matcher,
484                 const Matcher<Node*>& base_matcher,
485                 const Matcher<Node*>& index_matcher,
486                 const Matcher<Node*>& value_matcher,
487                 const Matcher<Node*>& effect_matcher,
488                 const Matcher<Node*>& control_matcher)
489      : NodeMatcher(IrOpcode::kStore),
490        type_matcher_(type_matcher),
491        write_barrier_matcher_(write_barrier_matcher),
492        base_matcher_(base_matcher),
493        index_matcher_(index_matcher),
494        value_matcher_(value_matcher),
495        effect_matcher_(effect_matcher),
496        control_matcher_(control_matcher) {}
497
498  virtual void DescribeTo(std::ostream* os) const OVERRIDE {
499    NodeMatcher::DescribeTo(os);
500    *os << " whose type (";
501    type_matcher_.DescribeTo(os);
502    *os << "), write barrier (";
503    write_barrier_matcher_.DescribeTo(os);
504    *os << "), base (";
505    base_matcher_.DescribeTo(os);
506    *os << "), index (";
507    index_matcher_.DescribeTo(os);
508    *os << "), value (";
509    value_matcher_.DescribeTo(os);
510    *os << "), effect (";
511    effect_matcher_.DescribeTo(os);
512    *os << ") and control (";
513    control_matcher_.DescribeTo(os);
514    *os << ")";
515  }
516
517  virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
518      OVERRIDE {
519    return (NodeMatcher::MatchAndExplain(node, listener) &&
520            PrintMatchAndExplain(
521                OpParameter<StoreRepresentation>(node).machine_type(), "type",
522                type_matcher_, listener) &&
523            PrintMatchAndExplain(
524                OpParameter<StoreRepresentation>(node).write_barrier_kind(),
525                "write barrier", write_barrier_matcher_, listener) &&
526            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
527                                 base_matcher_, listener) &&
528            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
529                                 "index", index_matcher_, listener) &&
530            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2),
531                                 "value", value_matcher_, listener) &&
532            PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
533                                 effect_matcher_, listener) &&
534            PrintMatchAndExplain(NodeProperties::GetControlInput(node),
535                                 "control", control_matcher_, listener));
536  }
537
538 private:
539  const Matcher<MachineType> type_matcher_;
540  const Matcher<WriteBarrierKind> write_barrier_matcher_;
541  const Matcher<Node*> base_matcher_;
542  const Matcher<Node*> index_matcher_;
543  const Matcher<Node*> value_matcher_;
544  const Matcher<Node*> effect_matcher_;
545  const Matcher<Node*> control_matcher_;
546};
547
548
549class IsBinopMatcher FINAL : public NodeMatcher {
550 public:
551  IsBinopMatcher(IrOpcode::Value opcode, const Matcher<Node*>& lhs_matcher,
552                 const Matcher<Node*>& rhs_matcher)
553      : NodeMatcher(opcode),
554        lhs_matcher_(lhs_matcher),
555        rhs_matcher_(rhs_matcher) {}
556
557  virtual void DescribeTo(std::ostream* os) const OVERRIDE {
558    NodeMatcher::DescribeTo(os);
559    *os << " whose lhs (";
560    lhs_matcher_.DescribeTo(os);
561    *os << ") and rhs (";
562    rhs_matcher_.DescribeTo(os);
563    *os << ")";
564  }
565
566  virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
567      OVERRIDE {
568    return (NodeMatcher::MatchAndExplain(node, listener) &&
569            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "lhs",
570                                 lhs_matcher_, listener) &&
571            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "rhs",
572                                 rhs_matcher_, listener));
573  }
574
575 private:
576  const Matcher<Node*> lhs_matcher_;
577  const Matcher<Node*> rhs_matcher_;
578};
579
580
581class IsUnopMatcher FINAL : public NodeMatcher {
582 public:
583  IsUnopMatcher(IrOpcode::Value opcode, const Matcher<Node*>& input_matcher)
584      : NodeMatcher(opcode), input_matcher_(input_matcher) {}
585
586  virtual void DescribeTo(std::ostream* os) const OVERRIDE {
587    NodeMatcher::DescribeTo(os);
588    *os << " whose input (";
589    input_matcher_.DescribeTo(os);
590    *os << ")";
591  }
592
593  virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
594      OVERRIDE {
595    return (NodeMatcher::MatchAndExplain(node, listener) &&
596            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
597                                 "input", input_matcher_, listener));
598  }
599
600 private:
601  const Matcher<Node*> input_matcher_;
602};
603}
604
605
606Matcher<Node*> IsBranch(const Matcher<Node*>& value_matcher,
607                        const Matcher<Node*>& control_matcher) {
608  return MakeMatcher(new IsBranchMatcher(value_matcher, control_matcher));
609}
610
611
612Matcher<Node*> IsMerge(const Matcher<Node*>& control0_matcher,
613                       const Matcher<Node*>& control1_matcher) {
614  return MakeMatcher(new IsMergeMatcher(control0_matcher, control1_matcher));
615}
616
617
618Matcher<Node*> IsIfTrue(const Matcher<Node*>& control_matcher) {
619  return MakeMatcher(new IsControl1Matcher(IrOpcode::kIfTrue, control_matcher));
620}
621
622
623Matcher<Node*> IsIfFalse(const Matcher<Node*>& control_matcher) {
624  return MakeMatcher(
625      new IsControl1Matcher(IrOpcode::kIfFalse, control_matcher));
626}
627
628
629Matcher<Node*> IsControlEffect(const Matcher<Node*>& control_matcher) {
630  return MakeMatcher(
631      new IsControl1Matcher(IrOpcode::kControlEffect, control_matcher));
632}
633
634
635Matcher<Node*> IsValueEffect(const Matcher<Node*>& value_matcher) {
636  return MakeMatcher(new IsUnopMatcher(IrOpcode::kValueEffect, value_matcher));
637}
638
639
640Matcher<Node*> IsFinish(const Matcher<Node*>& value_matcher,
641                        const Matcher<Node*>& effect_matcher) {
642  return MakeMatcher(new IsFinishMatcher(value_matcher, effect_matcher));
643}
644
645
646Matcher<Node*> IsExternalConstant(
647    const Matcher<ExternalReference>& value_matcher) {
648  return MakeMatcher(new IsConstantMatcher<ExternalReference>(
649      IrOpcode::kExternalConstant, value_matcher));
650}
651
652
653Matcher<Node*> IsHeapConstant(
654    const Matcher<Unique<HeapObject> >& value_matcher) {
655  return MakeMatcher(new IsConstantMatcher<Unique<HeapObject> >(
656      IrOpcode::kHeapConstant, value_matcher));
657}
658
659
660Matcher<Node*> IsInt32Constant(const Matcher<int32_t>& value_matcher) {
661  return MakeMatcher(
662      new IsConstantMatcher<int32_t>(IrOpcode::kInt32Constant, value_matcher));
663}
664
665
666Matcher<Node*> IsInt64Constant(const Matcher<int64_t>& value_matcher) {
667  return MakeMatcher(
668      new IsConstantMatcher<int64_t>(IrOpcode::kInt64Constant, value_matcher));
669}
670
671
672Matcher<Node*> IsFloat32Constant(const Matcher<float>& value_matcher) {
673  return MakeMatcher(
674      new IsConstantMatcher<float>(IrOpcode::kFloat32Constant, value_matcher));
675}
676
677
678Matcher<Node*> IsFloat64Constant(const Matcher<double>& value_matcher) {
679  return MakeMatcher(
680      new IsConstantMatcher<double>(IrOpcode::kFloat64Constant, value_matcher));
681}
682
683
684Matcher<Node*> IsNumberConstant(const Matcher<double>& value_matcher) {
685  return MakeMatcher(
686      new IsConstantMatcher<double>(IrOpcode::kNumberConstant, value_matcher));
687}
688
689
690Matcher<Node*> IsPhi(const Matcher<MachineType>& type_matcher,
691                     const Matcher<Node*>& value0_matcher,
692                     const Matcher<Node*>& value1_matcher,
693                     const Matcher<Node*>& merge_matcher) {
694  return MakeMatcher(new IsPhiMatcher(type_matcher, value0_matcher,
695                                      value1_matcher, merge_matcher));
696}
697
698
699Matcher<Node*> IsProjection(const Matcher<size_t>& index_matcher,
700                            const Matcher<Node*>& base_matcher) {
701  return MakeMatcher(new IsProjectionMatcher(index_matcher, base_matcher));
702}
703
704
705Matcher<Node*> IsCall(const Matcher<CallDescriptor*>& descriptor_matcher,
706                      const Matcher<Node*>& value0_matcher,
707                      const Matcher<Node*>& value1_matcher,
708                      const Matcher<Node*>& value2_matcher,
709                      const Matcher<Node*>& value3_matcher,
710                      const Matcher<Node*>& effect_matcher,
711                      const Matcher<Node*>& control_matcher) {
712  return MakeMatcher(new IsCallMatcher(
713      descriptor_matcher, value0_matcher, value1_matcher, value2_matcher,
714      value3_matcher, effect_matcher, control_matcher));
715}
716
717
718Matcher<Node*> IsLoad(const Matcher<LoadRepresentation>& rep_matcher,
719                      const Matcher<Node*>& base_matcher,
720                      const Matcher<Node*>& index_matcher,
721                      const Matcher<Node*>& effect_matcher) {
722  return MakeMatcher(new IsLoadMatcher(rep_matcher, base_matcher, index_matcher,
723                                       effect_matcher));
724}
725
726
727Matcher<Node*> IsStore(const Matcher<MachineType>& type_matcher,
728                       const Matcher<WriteBarrierKind>& write_barrier_matcher,
729                       const Matcher<Node*>& base_matcher,
730                       const Matcher<Node*>& index_matcher,
731                       const Matcher<Node*>& value_matcher,
732                       const Matcher<Node*>& effect_matcher,
733                       const Matcher<Node*>& control_matcher) {
734  return MakeMatcher(new IsStoreMatcher(
735      type_matcher, write_barrier_matcher, base_matcher, index_matcher,
736      value_matcher, effect_matcher, control_matcher));
737}
738
739
740#define IS_BINOP_MATCHER(Name)                                            \
741  Matcher<Node*> Is##Name(const Matcher<Node*>& lhs_matcher,              \
742                          const Matcher<Node*>& rhs_matcher) {            \
743    return MakeMatcher(                                                   \
744        new IsBinopMatcher(IrOpcode::k##Name, lhs_matcher, rhs_matcher)); \
745  }
746IS_BINOP_MATCHER(NumberLessThan)
747IS_BINOP_MATCHER(Word32And)
748IS_BINOP_MATCHER(Word32Sar)
749IS_BINOP_MATCHER(Word32Shl)
750IS_BINOP_MATCHER(Word32Ror)
751IS_BINOP_MATCHER(Word32Equal)
752IS_BINOP_MATCHER(Word64And)
753IS_BINOP_MATCHER(Word64Sar)
754IS_BINOP_MATCHER(Word64Shl)
755IS_BINOP_MATCHER(Word64Equal)
756IS_BINOP_MATCHER(Int32AddWithOverflow)
757IS_BINOP_MATCHER(Int32Mul)
758IS_BINOP_MATCHER(Uint32LessThanOrEqual)
759#undef IS_BINOP_MATCHER
760
761
762#define IS_UNOP_MATCHER(Name)                                                \
763  Matcher<Node*> Is##Name(const Matcher<Node*>& input_matcher) {             \
764    return MakeMatcher(new IsUnopMatcher(IrOpcode::k##Name, input_matcher)); \
765  }
766IS_UNOP_MATCHER(ChangeFloat64ToInt32)
767IS_UNOP_MATCHER(ChangeFloat64ToUint32)
768IS_UNOP_MATCHER(ChangeInt32ToFloat64)
769IS_UNOP_MATCHER(ChangeInt32ToInt64)
770IS_UNOP_MATCHER(ChangeUint32ToFloat64)
771IS_UNOP_MATCHER(ChangeUint32ToUint64)
772IS_UNOP_MATCHER(TruncateFloat64ToInt32)
773IS_UNOP_MATCHER(TruncateInt64ToInt32)
774IS_UNOP_MATCHER(Float64Sqrt)
775#undef IS_UNOP_MATCHER
776
777}  // namespace compiler
778}  // namespace internal
779}  // namespace v8
780