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
11 using testing::_;
12 using testing::MakeMatcher;
13 using testing::MatcherInterface;
14 using testing::MatchResultListener;
15 using testing::StringMatchResultListener;
16
17 namespace v8 {
18 namespace internal {
19
20 // TODO(bmeurer): Find a new home for these functions.
21 template <typename T>
operator <<(std::ostream & os,const Unique<T> & value)22 inline std::ostream& operator<<(std::ostream& os, const Unique<T>& value) {
23 return os << *value.handle();
24 }
operator <<(std::ostream & os,const ExternalReference & value)25 inline 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
32 namespace compiler {
33
GraphTest(int num_parameters)34 GraphTest::GraphTest(int num_parameters) : common_(zone()), graph_(zone()) {
35 graph()->SetStart(graph()->NewNode(common()->Start(num_parameters)));
36 }
37
38
~GraphTest()39 GraphTest::~GraphTest() {}
40
41
Parameter(int32_t index)42 Node* GraphTest::Parameter(int32_t index) {
43 return graph()->NewNode(common()->Parameter(index), graph()->start());
44 }
45
46
Float32Constant(volatile float value)47 Node* GraphTest::Float32Constant(volatile float value) {
48 return graph()->NewNode(common()->Float32Constant(value));
49 }
50
51
Float64Constant(volatile double value)52 Node* GraphTest::Float64Constant(volatile double value) {
53 return graph()->NewNode(common()->Float64Constant(value));
54 }
55
56
Int32Constant(int32_t value)57 Node* GraphTest::Int32Constant(int32_t value) {
58 return graph()->NewNode(common()->Int32Constant(value));
59 }
60
61
Int64Constant(int64_t value)62 Node* GraphTest::Int64Constant(int64_t value) {
63 return graph()->NewNode(common()->Int64Constant(value));
64 }
65
66
NumberConstant(volatile double value)67 Node* GraphTest::NumberConstant(volatile double value) {
68 return graph()->NewNode(common()->NumberConstant(value));
69 }
70
71
HeapConstant(const Unique<HeapObject> & value)72 Node* GraphTest::HeapConstant(const Unique<HeapObject>& value) {
73 return graph()->NewNode(common()->HeapConstant(value));
74 }
75
76
FalseConstant()77 Node* GraphTest::FalseConstant() {
78 return HeapConstant(
79 Unique<HeapObject>::CreateImmovable(factory()->false_value()));
80 }
81
82
TrueConstant()83 Node* GraphTest::TrueConstant() {
84 return HeapConstant(
85 Unique<HeapObject>::CreateImmovable(factory()->true_value()));
86 }
87
88
IsFalseConstant()89 Matcher<Node*> GraphTest::IsFalseConstant() {
90 return IsHeapConstant(
91 Unique<HeapObject>::CreateImmovable(factory()->false_value()));
92 }
93
94
IsTrueConstant()95 Matcher<Node*> GraphTest::IsTrueConstant() {
96 return IsHeapConstant(
97 Unique<HeapObject>::CreateImmovable(factory()->true_value()));
98 }
99
100 namespace {
101
102 template <typename T>
PrintMatchAndExplain(const T & value,const char * value_name,const Matcher<T> & value_matcher,MatchResultListener * listener)103 bool 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
118 class NodeMatcher : public MatcherInterface<Node*> {
119 public:
NodeMatcher(IrOpcode::Value opcode)120 explicit NodeMatcher(IrOpcode::Value opcode) : opcode_(opcode) {}
121
DescribeTo(std::ostream * os) const122 virtual void DescribeTo(std::ostream* os) const OVERRIDE {
123 *os << "is a " << IrOpcode::Mnemonic(opcode_) << " node";
124 }
125
MatchAndExplain(Node * node,MatchResultListener * listener) const126 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
145 class IsBranchMatcher FINAL : public NodeMatcher {
146 public:
IsBranchMatcher(const Matcher<Node * > & value_matcher,const Matcher<Node * > & control_matcher)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
DescribeTo(std::ostream * os) const153 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
MatchAndExplain(Node * node,MatchResultListener * listener) const162 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
177 class IsMergeMatcher FINAL : public NodeMatcher {
178 public:
IsMergeMatcher(const Matcher<Node * > & control0_matcher,const Matcher<Node * > & control1_matcher)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
DescribeTo(std::ostream * os) const185 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
MatchAndExplain(Node * node,MatchResultListener * listener) const194 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
209 class IsControl1Matcher FINAL : public NodeMatcher {
210 public:
IsControl1Matcher(IrOpcode::Value opcode,const Matcher<Node * > & control_matcher)211 IsControl1Matcher(IrOpcode::Value opcode,
212 const Matcher<Node*>& control_matcher)
213 : NodeMatcher(opcode), control_matcher_(control_matcher) {}
214
DescribeTo(std::ostream * os) const215 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
MatchAndExplain(Node * node,MatchResultListener * listener) const222 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
234 class IsFinishMatcher FINAL : public NodeMatcher {
235 public:
IsFinishMatcher(const Matcher<Node * > & value_matcher,const Matcher<Node * > & effect_matcher)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
DescribeTo(std::ostream * os) const242 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
MatchAndExplain(Node * node,MatchResultListener * listener) const251 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
266 template <typename T>
267 class IsConstantMatcher FINAL : public NodeMatcher {
268 public:
IsConstantMatcher(IrOpcode::Value opcode,const Matcher<T> & value_matcher)269 IsConstantMatcher(IrOpcode::Value opcode, const Matcher<T>& value_matcher)
270 : NodeMatcher(opcode), value_matcher_(value_matcher) {}
271
DescribeTo(std::ostream * os) const272 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
MatchAndExplain(Node * node,MatchResultListener * listener) const279 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
291 class IsPhiMatcher FINAL : public NodeMatcher {
292 public:
IsPhiMatcher(const Matcher<MachineType> & type_matcher,const Matcher<Node * > & value0_matcher,const Matcher<Node * > & value1_matcher,const Matcher<Node * > & control_matcher)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
DescribeTo(std::ostream * os) const303 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
MatchAndExplain(Node * node,MatchResultListener * listener) const316 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
337 class IsProjectionMatcher FINAL : public NodeMatcher {
338 public:
IsProjectionMatcher(const Matcher<size_t> & index_matcher,const Matcher<Node * > & base_matcher)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
DescribeTo(std::ostream * os) const345 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
MatchAndExplain(Node * node,MatchResultListener * listener) const354 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
369 class IsCallMatcher FINAL : public NodeMatcher {
370 public:
IsCallMatcher(const Matcher<CallDescriptor * > & descriptor_matcher,const Matcher<Node * > & value0_matcher,const Matcher<Node * > & value1_matcher,const Matcher<Node * > & value2_matcher,const Matcher<Node * > & value3_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)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
DescribeTo(std::ostream * os) const387 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
MatchAndExplain(Node * node,MatchResultListener * listener) const404 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
434 class IsLoadMatcher FINAL : public NodeMatcher {
435 public:
IsLoadMatcher(const Matcher<LoadRepresentation> & rep_matcher,const Matcher<Node * > & base_matcher,const Matcher<Node * > & index_matcher,const Matcher<Node * > & effect_matcher)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
DescribeTo(std::ostream * os) const446 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
MatchAndExplain(Node * node,MatchResultListener * listener) const459 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
480 class IsStoreMatcher FINAL : public NodeMatcher {
481 public:
IsStoreMatcher(const Matcher<MachineType> & type_matcher,const Matcher<WriteBarrierKind> write_barrier_matcher,const Matcher<Node * > & base_matcher,const Matcher<Node * > & index_matcher,const Matcher<Node * > & value_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)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
DescribeTo(std::ostream * os) const498 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
MatchAndExplain(Node * node,MatchResultListener * listener) const517 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
549 class IsBinopMatcher FINAL : public NodeMatcher {
550 public:
IsBinopMatcher(IrOpcode::Value opcode,const Matcher<Node * > & lhs_matcher,const Matcher<Node * > & rhs_matcher)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
DescribeTo(std::ostream * os) const557 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
MatchAndExplain(Node * node,MatchResultListener * listener) const566 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
581 class IsUnopMatcher FINAL : public NodeMatcher {
582 public:
IsUnopMatcher(IrOpcode::Value opcode,const Matcher<Node * > & input_matcher)583 IsUnopMatcher(IrOpcode::Value opcode, const Matcher<Node*>& input_matcher)
584 : NodeMatcher(opcode), input_matcher_(input_matcher) {}
585
DescribeTo(std::ostream * os) const586 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
MatchAndExplain(Node * node,MatchResultListener * listener) const593 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
IsBranch(const Matcher<Node * > & value_matcher,const Matcher<Node * > & control_matcher)606 Matcher<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
IsMerge(const Matcher<Node * > & control0_matcher,const Matcher<Node * > & control1_matcher)612 Matcher<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
IsIfTrue(const Matcher<Node * > & control_matcher)618 Matcher<Node*> IsIfTrue(const Matcher<Node*>& control_matcher) {
619 return MakeMatcher(new IsControl1Matcher(IrOpcode::kIfTrue, control_matcher));
620 }
621
622
IsIfFalse(const Matcher<Node * > & control_matcher)623 Matcher<Node*> IsIfFalse(const Matcher<Node*>& control_matcher) {
624 return MakeMatcher(
625 new IsControl1Matcher(IrOpcode::kIfFalse, control_matcher));
626 }
627
628
IsControlEffect(const Matcher<Node * > & control_matcher)629 Matcher<Node*> IsControlEffect(const Matcher<Node*>& control_matcher) {
630 return MakeMatcher(
631 new IsControl1Matcher(IrOpcode::kControlEffect, control_matcher));
632 }
633
634
IsValueEffect(const Matcher<Node * > & value_matcher)635 Matcher<Node*> IsValueEffect(const Matcher<Node*>& value_matcher) {
636 return MakeMatcher(new IsUnopMatcher(IrOpcode::kValueEffect, value_matcher));
637 }
638
639
IsFinish(const Matcher<Node * > & value_matcher,const Matcher<Node * > & effect_matcher)640 Matcher<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
IsExternalConstant(const Matcher<ExternalReference> & value_matcher)646 Matcher<Node*> IsExternalConstant(
647 const Matcher<ExternalReference>& value_matcher) {
648 return MakeMatcher(new IsConstantMatcher<ExternalReference>(
649 IrOpcode::kExternalConstant, value_matcher));
650 }
651
652
IsHeapConstant(const Matcher<Unique<HeapObject>> & value_matcher)653 Matcher<Node*> IsHeapConstant(
654 const Matcher<Unique<HeapObject> >& value_matcher) {
655 return MakeMatcher(new IsConstantMatcher<Unique<HeapObject> >(
656 IrOpcode::kHeapConstant, value_matcher));
657 }
658
659
IsInt32Constant(const Matcher<int32_t> & value_matcher)660 Matcher<Node*> IsInt32Constant(const Matcher<int32_t>& value_matcher) {
661 return MakeMatcher(
662 new IsConstantMatcher<int32_t>(IrOpcode::kInt32Constant, value_matcher));
663 }
664
665
IsInt64Constant(const Matcher<int64_t> & value_matcher)666 Matcher<Node*> IsInt64Constant(const Matcher<int64_t>& value_matcher) {
667 return MakeMatcher(
668 new IsConstantMatcher<int64_t>(IrOpcode::kInt64Constant, value_matcher));
669 }
670
671
IsFloat32Constant(const Matcher<float> & value_matcher)672 Matcher<Node*> IsFloat32Constant(const Matcher<float>& value_matcher) {
673 return MakeMatcher(
674 new IsConstantMatcher<float>(IrOpcode::kFloat32Constant, value_matcher));
675 }
676
677
IsFloat64Constant(const Matcher<double> & value_matcher)678 Matcher<Node*> IsFloat64Constant(const Matcher<double>& value_matcher) {
679 return MakeMatcher(
680 new IsConstantMatcher<double>(IrOpcode::kFloat64Constant, value_matcher));
681 }
682
683
IsNumberConstant(const Matcher<double> & value_matcher)684 Matcher<Node*> IsNumberConstant(const Matcher<double>& value_matcher) {
685 return MakeMatcher(
686 new IsConstantMatcher<double>(IrOpcode::kNumberConstant, value_matcher));
687 }
688
689
IsPhi(const Matcher<MachineType> & type_matcher,const Matcher<Node * > & value0_matcher,const Matcher<Node * > & value1_matcher,const Matcher<Node * > & merge_matcher)690 Matcher<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
IsProjection(const Matcher<size_t> & index_matcher,const Matcher<Node * > & base_matcher)699 Matcher<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
IsCall(const Matcher<CallDescriptor * > & descriptor_matcher,const Matcher<Node * > & value0_matcher,const Matcher<Node * > & value1_matcher,const Matcher<Node * > & value2_matcher,const Matcher<Node * > & value3_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)705 Matcher<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
IsLoad(const Matcher<LoadRepresentation> & rep_matcher,const Matcher<Node * > & base_matcher,const Matcher<Node * > & index_matcher,const Matcher<Node * > & effect_matcher)718 Matcher<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
IsStore(const Matcher<MachineType> & type_matcher,const Matcher<WriteBarrierKind> & write_barrier_matcher,const Matcher<Node * > & base_matcher,const Matcher<Node * > & index_matcher,const Matcher<Node * > & value_matcher,const Matcher<Node * > & effect_matcher,const Matcher<Node * > & control_matcher)727 Matcher<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 }
746 IS_BINOP_MATCHER(NumberLessThan)
747 IS_BINOP_MATCHER(Word32And)
748 IS_BINOP_MATCHER(Word32Sar)
749 IS_BINOP_MATCHER(Word32Shl)
750 IS_BINOP_MATCHER(Word32Ror)
751 IS_BINOP_MATCHER(Word32Equal)
752 IS_BINOP_MATCHER(Word64And)
753 IS_BINOP_MATCHER(Word64Sar)
754 IS_BINOP_MATCHER(Word64Shl)
755 IS_BINOP_MATCHER(Word64Equal)
756 IS_BINOP_MATCHER(Int32AddWithOverflow)
757 IS_BINOP_MATCHER(Int32Mul)
758 IS_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 }
766 IS_UNOP_MATCHER(ChangeFloat64ToInt32)
767 IS_UNOP_MATCHER(ChangeFloat64ToUint32)
768 IS_UNOP_MATCHER(ChangeInt32ToFloat64)
769 IS_UNOP_MATCHER(ChangeInt32ToInt64)
770 IS_UNOP_MATCHER(ChangeUint32ToFloat64)
771 IS_UNOP_MATCHER(ChangeUint32ToUint64)
772 IS_UNOP_MATCHER(TruncateFloat64ToInt32)
773 IS_UNOP_MATCHER(TruncateInt64ToInt32)
774 IS_UNOP_MATCHER(Float64Sqrt)
775 #undef IS_UNOP_MATCHER
776
777 } // namespace compiler
778 } // namespace internal
779 } // namespace v8
780