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