OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "test/unittests/compiler/graph-unittest.h" | 5 #include "test/unittests/compiler/graph-unittest.h" |
6 | 6 |
7 #include <ostream> // NOLINT(readability/streams) | 7 #include <ostream> // NOLINT(readability/streams) |
8 | 8 |
9 #include "src/compiler/node-properties-inl.h" | 9 #include "src/compiler/node-properties-inl.h" |
10 #include "src/compiler/simplified-operator.h" | 10 #include "test/unittests/compiler/node-test-utils.h" |
11 | |
12 using testing::_; | |
13 using testing::MakeMatcher; | |
14 using testing::MatcherInterface; | |
15 using testing::MatchResultListener; | |
16 using testing::StringMatchResultListener; | |
17 | 11 |
18 namespace v8 { | 12 namespace v8 { |
19 namespace internal { | 13 namespace internal { |
20 namespace compiler { | 14 namespace compiler { |
21 | 15 |
22 GraphTest::GraphTest(int num_parameters) : common_(zone()), graph_(zone()) { | 16 GraphTest::GraphTest(int num_parameters) : common_(zone()), graph_(zone()) { |
23 graph()->SetStart(graph()->NewNode(common()->Start(num_parameters))); | 17 graph()->SetStart(graph()->NewNode(common()->Start(num_parameters))); |
24 } | 18 } |
25 | 19 |
26 | 20 |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 return IsHeapConstant( | 86 return IsHeapConstant( |
93 Unique<HeapObject>::CreateImmovable(factory()->false_value())); | 87 Unique<HeapObject>::CreateImmovable(factory()->false_value())); |
94 } | 88 } |
95 | 89 |
96 | 90 |
97 Matcher<Node*> GraphTest::IsTrueConstant() { | 91 Matcher<Node*> GraphTest::IsTrueConstant() { |
98 return IsHeapConstant( | 92 return IsHeapConstant( |
99 Unique<HeapObject>::CreateImmovable(factory()->true_value())); | 93 Unique<HeapObject>::CreateImmovable(factory()->true_value())); |
100 } | 94 } |
101 | 95 |
102 namespace { | |
103 | |
104 template <typename T> | |
105 bool PrintMatchAndExplain(const T& value, const char* value_name, | |
106 const Matcher<T>& value_matcher, | |
107 MatchResultListener* listener) { | |
108 StringMatchResultListener value_listener; | |
109 if (!value_matcher.MatchAndExplain(value, &value_listener)) { | |
110 *listener << "whose " << value_name << " " << value << " doesn't match"; | |
111 if (value_listener.str() != "") { | |
112 *listener << ", " << value_listener.str(); | |
113 } | |
114 return false; | |
115 } | |
116 return true; | |
117 } | |
118 | |
119 | |
120 class NodeMatcher : public MatcherInterface<Node*> { | |
121 public: | |
122 explicit NodeMatcher(IrOpcode::Value opcode) : opcode_(opcode) {} | |
123 | |
124 virtual void DescribeTo(std::ostream* os) const OVERRIDE { | |
125 *os << "is a " << IrOpcode::Mnemonic(opcode_) << " node"; | |
126 } | |
127 | |
128 virtual bool MatchAndExplain(Node* node, | |
129 MatchResultListener* listener) const OVERRIDE { | |
130 if (node == NULL) { | |
131 *listener << "which is NULL"; | |
132 return false; | |
133 } | |
134 if (node->opcode() != opcode_) { | |
135 *listener << "whose opcode is " << IrOpcode::Mnemonic(node->opcode()) | |
136 << " but should have been " << IrOpcode::Mnemonic(opcode_); | |
137 return false; | |
138 } | |
139 return true; | |
140 } | |
141 | |
142 private: | |
143 const IrOpcode::Value opcode_; | |
144 }; | |
145 | |
146 | |
147 class IsBranchMatcher FINAL : public NodeMatcher { | |
148 public: | |
149 IsBranchMatcher(const Matcher<Node*>& value_matcher, | |
150 const Matcher<Node*>& control_matcher) | |
151 : NodeMatcher(IrOpcode::kBranch), | |
152 value_matcher_(value_matcher), | |
153 control_matcher_(control_matcher) {} | |
154 | |
155 virtual void DescribeTo(std::ostream* os) const OVERRIDE { | |
156 NodeMatcher::DescribeTo(os); | |
157 *os << " whose value ("; | |
158 value_matcher_.DescribeTo(os); | |
159 *os << ") and control ("; | |
160 control_matcher_.DescribeTo(os); | |
161 *os << ")"; | |
162 } | |
163 | |
164 virtual bool MatchAndExplain(Node* node, | |
165 MatchResultListener* listener) const OVERRIDE { | |
166 return (NodeMatcher::MatchAndExplain(node, listener) && | |
167 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), | |
168 "value", value_matcher_, listener) && | |
169 PrintMatchAndExplain(NodeProperties::GetControlInput(node), | |
170 "control", control_matcher_, listener)); | |
171 } | |
172 | |
173 private: | |
174 const Matcher<Node*> value_matcher_; | |
175 const Matcher<Node*> control_matcher_; | |
176 }; | |
177 | |
178 | |
179 class IsMergeMatcher FINAL : public NodeMatcher { | |
180 public: | |
181 IsMergeMatcher(const Matcher<Node*>& control0_matcher, | |
182 const Matcher<Node*>& control1_matcher) | |
183 : NodeMatcher(IrOpcode::kMerge), | |
184 control0_matcher_(control0_matcher), | |
185 control1_matcher_(control1_matcher) {} | |
186 | |
187 virtual void DescribeTo(std::ostream* os) const OVERRIDE { | |
188 NodeMatcher::DescribeTo(os); | |
189 *os << " whose control0 ("; | |
190 control0_matcher_.DescribeTo(os); | |
191 *os << ") and control1 ("; | |
192 control1_matcher_.DescribeTo(os); | |
193 *os << ")"; | |
194 } | |
195 | |
196 virtual bool MatchAndExplain(Node* node, | |
197 MatchResultListener* listener) const OVERRIDE { | |
198 return (NodeMatcher::MatchAndExplain(node, listener) && | |
199 PrintMatchAndExplain(NodeProperties::GetControlInput(node, 0), | |
200 "control0", control0_matcher_, listener) && | |
201 PrintMatchAndExplain(NodeProperties::GetControlInput(node, 1), | |
202 "control1", control1_matcher_, listener)); | |
203 } | |
204 | |
205 private: | |
206 const Matcher<Node*> control0_matcher_; | |
207 const Matcher<Node*> control1_matcher_; | |
208 }; | |
209 | |
210 | |
211 class IsControl1Matcher FINAL : public NodeMatcher { | |
212 public: | |
213 IsControl1Matcher(IrOpcode::Value opcode, | |
214 const Matcher<Node*>& control_matcher) | |
215 : NodeMatcher(opcode), control_matcher_(control_matcher) {} | |
216 | |
217 virtual void DescribeTo(std::ostream* os) const OVERRIDE { | |
218 NodeMatcher::DescribeTo(os); | |
219 *os << " whose control ("; | |
220 control_matcher_.DescribeTo(os); | |
221 *os << ")"; | |
222 } | |
223 | |
224 virtual bool MatchAndExplain(Node* node, | |
225 MatchResultListener* listener) const OVERRIDE { | |
226 return (NodeMatcher::MatchAndExplain(node, listener) && | |
227 PrintMatchAndExplain(NodeProperties::GetControlInput(node), | |
228 "control", control_matcher_, listener)); | |
229 } | |
230 | |
231 private: | |
232 const Matcher<Node*> control_matcher_; | |
233 }; | |
234 | |
235 | |
236 class IsFinishMatcher FINAL : public NodeMatcher { | |
237 public: | |
238 IsFinishMatcher(const Matcher<Node*>& value_matcher, | |
239 const Matcher<Node*>& effect_matcher) | |
240 : NodeMatcher(IrOpcode::kFinish), | |
241 value_matcher_(value_matcher), | |
242 effect_matcher_(effect_matcher) {} | |
243 | |
244 virtual void DescribeTo(std::ostream* os) const OVERRIDE { | |
245 NodeMatcher::DescribeTo(os); | |
246 *os << " whose value ("; | |
247 value_matcher_.DescribeTo(os); | |
248 *os << ") and effect ("; | |
249 effect_matcher_.DescribeTo(os); | |
250 *os << ")"; | |
251 } | |
252 | |
253 virtual bool MatchAndExplain(Node* node, | |
254 MatchResultListener* listener) const OVERRIDE { | |
255 return (NodeMatcher::MatchAndExplain(node, listener) && | |
256 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), | |
257 "value", value_matcher_, listener) && | |
258 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", | |
259 effect_matcher_, listener)); | |
260 } | |
261 | |
262 private: | |
263 const Matcher<Node*> value_matcher_; | |
264 const Matcher<Node*> effect_matcher_; | |
265 }; | |
266 | |
267 | |
268 template <typename T> | |
269 class IsConstantMatcher FINAL : public NodeMatcher { | |
270 public: | |
271 IsConstantMatcher(IrOpcode::Value opcode, const Matcher<T>& value_matcher) | |
272 : NodeMatcher(opcode), value_matcher_(value_matcher) {} | |
273 | |
274 virtual void DescribeTo(std::ostream* os) const OVERRIDE { | |
275 NodeMatcher::DescribeTo(os); | |
276 *os << " whose value ("; | |
277 value_matcher_.DescribeTo(os); | |
278 *os << ")"; | |
279 } | |
280 | |
281 virtual bool MatchAndExplain(Node* node, | |
282 MatchResultListener* listener) const OVERRIDE { | |
283 return (NodeMatcher::MatchAndExplain(node, listener) && | |
284 PrintMatchAndExplain(OpParameter<T>(node), "value", value_matcher_, | |
285 listener)); | |
286 } | |
287 | |
288 private: | |
289 const Matcher<T> value_matcher_; | |
290 }; | |
291 | |
292 | |
293 class IsPhiMatcher FINAL : public NodeMatcher { | |
294 public: | |
295 IsPhiMatcher(const Matcher<MachineType>& type_matcher, | |
296 const Matcher<Node*>& value0_matcher, | |
297 const Matcher<Node*>& value1_matcher, | |
298 const Matcher<Node*>& control_matcher) | |
299 : NodeMatcher(IrOpcode::kPhi), | |
300 type_matcher_(type_matcher), | |
301 value0_matcher_(value0_matcher), | |
302 value1_matcher_(value1_matcher), | |
303 control_matcher_(control_matcher) {} | |
304 | |
305 virtual void DescribeTo(std::ostream* os) const OVERRIDE { | |
306 NodeMatcher::DescribeTo(os); | |
307 *os << " whose type ("; | |
308 type_matcher_.DescribeTo(os); | |
309 *os << "), value0 ("; | |
310 value0_matcher_.DescribeTo(os); | |
311 *os << "), value1 ("; | |
312 value1_matcher_.DescribeTo(os); | |
313 *os << ") and control ("; | |
314 control_matcher_.DescribeTo(os); | |
315 *os << ")"; | |
316 } | |
317 | |
318 virtual bool MatchAndExplain(Node* node, | |
319 MatchResultListener* listener) const OVERRIDE { | |
320 return (NodeMatcher::MatchAndExplain(node, listener) && | |
321 PrintMatchAndExplain(OpParameter<MachineType>(node), "type", | |
322 type_matcher_, listener) && | |
323 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), | |
324 "value0", value0_matcher_, listener) && | |
325 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), | |
326 "value1", value1_matcher_, listener) && | |
327 PrintMatchAndExplain(NodeProperties::GetControlInput(node), | |
328 "control", control_matcher_, listener)); | |
329 } | |
330 | |
331 private: | |
332 const Matcher<MachineType> type_matcher_; | |
333 const Matcher<Node*> value0_matcher_; | |
334 const Matcher<Node*> value1_matcher_; | |
335 const Matcher<Node*> control_matcher_; | |
336 }; | |
337 | |
338 | |
339 class IsProjectionMatcher FINAL : public NodeMatcher { | |
340 public: | |
341 IsProjectionMatcher(const Matcher<size_t>& index_matcher, | |
342 const Matcher<Node*>& base_matcher) | |
343 : NodeMatcher(IrOpcode::kProjection), | |
344 index_matcher_(index_matcher), | |
345 base_matcher_(base_matcher) {} | |
346 | |
347 virtual void DescribeTo(std::ostream* os) const OVERRIDE { | |
348 NodeMatcher::DescribeTo(os); | |
349 *os << " whose index ("; | |
350 index_matcher_.DescribeTo(os); | |
351 *os << ") and base ("; | |
352 base_matcher_.DescribeTo(os); | |
353 *os << ")"; | |
354 } | |
355 | |
356 virtual bool MatchAndExplain(Node* node, | |
357 MatchResultListener* listener) const OVERRIDE { | |
358 return (NodeMatcher::MatchAndExplain(node, listener) && | |
359 PrintMatchAndExplain(OpParameter<size_t>(node), "index", | |
360 index_matcher_, listener) && | |
361 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base", | |
362 base_matcher_, listener)); | |
363 } | |
364 | |
365 private: | |
366 const Matcher<size_t> index_matcher_; | |
367 const Matcher<Node*> base_matcher_; | |
368 }; | |
369 | |
370 | |
371 class IsCallMatcher FINAL : public NodeMatcher { | |
372 public: | |
373 IsCallMatcher(const Matcher<CallDescriptor*>& descriptor_matcher, | |
374 const Matcher<Node*>& value0_matcher, | |
375 const Matcher<Node*>& value1_matcher, | |
376 const Matcher<Node*>& value2_matcher, | |
377 const Matcher<Node*>& value3_matcher, | |
378 const Matcher<Node*>& effect_matcher, | |
379 const Matcher<Node*>& control_matcher) | |
380 : NodeMatcher(IrOpcode::kCall), | |
381 descriptor_matcher_(descriptor_matcher), | |
382 value0_matcher_(value0_matcher), | |
383 value1_matcher_(value1_matcher), | |
384 value2_matcher_(value2_matcher), | |
385 value3_matcher_(value3_matcher), | |
386 effect_matcher_(effect_matcher), | |
387 control_matcher_(control_matcher) {} | |
388 | |
389 virtual void DescribeTo(std::ostream* os) const OVERRIDE { | |
390 NodeMatcher::DescribeTo(os); | |
391 *os << " whose value0 ("; | |
392 value0_matcher_.DescribeTo(os); | |
393 *os << ") and value1 ("; | |
394 value1_matcher_.DescribeTo(os); | |
395 *os << ") and value2 ("; | |
396 value2_matcher_.DescribeTo(os); | |
397 *os << ") and value3 ("; | |
398 value3_matcher_.DescribeTo(os); | |
399 *os << ") and effect ("; | |
400 effect_matcher_.DescribeTo(os); | |
401 *os << ") and control ("; | |
402 control_matcher_.DescribeTo(os); | |
403 *os << ")"; | |
404 } | |
405 | |
406 virtual bool MatchAndExplain(Node* node, | |
407 MatchResultListener* listener) const OVERRIDE { | |
408 return (NodeMatcher::MatchAndExplain(node, listener) && | |
409 PrintMatchAndExplain(OpParameter<CallDescriptor*>(node), | |
410 "descriptor", descriptor_matcher_, listener) && | |
411 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), | |
412 "value0", value0_matcher_, listener) && | |
413 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), | |
414 "value1", value1_matcher_, listener) && | |
415 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2), | |
416 "value2", value2_matcher_, listener) && | |
417 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 3), | |
418 "value3", value3_matcher_, listener) && | |
419 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", | |
420 effect_matcher_, listener) && | |
421 PrintMatchAndExplain(NodeProperties::GetControlInput(node), | |
422 "control", control_matcher_, listener)); | |
423 } | |
424 | |
425 private: | |
426 const Matcher<CallDescriptor*> descriptor_matcher_; | |
427 const Matcher<Node*> value0_matcher_; | |
428 const Matcher<Node*> value1_matcher_; | |
429 const Matcher<Node*> value2_matcher_; | |
430 const Matcher<Node*> value3_matcher_; | |
431 const Matcher<Node*> effect_matcher_; | |
432 const Matcher<Node*> control_matcher_; | |
433 }; | |
434 | |
435 | |
436 class IsLoadFieldMatcher FINAL : public NodeMatcher { | |
437 public: | |
438 IsLoadFieldMatcher(const Matcher<FieldAccess>& access_matcher, | |
439 const Matcher<Node*>& base_matcher, | |
440 const Matcher<Node*>& effect_matcher) | |
441 : NodeMatcher(IrOpcode::kLoadField), | |
442 access_matcher_(access_matcher), | |
443 base_matcher_(base_matcher), | |
444 effect_matcher_(effect_matcher) {} | |
445 | |
446 virtual void DescribeTo(std::ostream* os) const OVERRIDE { | |
447 NodeMatcher::DescribeTo(os); | |
448 *os << " whose access ("; | |
449 access_matcher_.DescribeTo(os); | |
450 *os << "), base ("; | |
451 base_matcher_.DescribeTo(os); | |
452 *os << ") and effect ("; | |
453 effect_matcher_.DescribeTo(os); | |
454 *os << ")"; | |
455 } | |
456 | |
457 virtual bool MatchAndExplain(Node* node, | |
458 MatchResultListener* listener) const OVERRIDE { | |
459 return (NodeMatcher::MatchAndExplain(node, listener) && | |
460 PrintMatchAndExplain(OpParameter<FieldAccess>(node), "access", | |
461 access_matcher_, listener) && | |
462 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base", | |
463 base_matcher_, listener) && | |
464 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", | |
465 effect_matcher_, listener)); | |
466 } | |
467 | |
468 private: | |
469 const Matcher<FieldAccess> access_matcher_; | |
470 const Matcher<Node*> base_matcher_; | |
471 const Matcher<Node*> effect_matcher_; | |
472 }; | |
473 | |
474 | |
475 class IsLoadElementMatcher FINAL : public NodeMatcher { | |
476 public: | |
477 IsLoadElementMatcher(const Matcher<ElementAccess>& access_matcher, | |
478 const Matcher<Node*>& base_matcher, | |
479 const Matcher<Node*>& index_matcher, | |
480 const Matcher<Node*>& length_matcher, | |
481 const Matcher<Node*>& effect_matcher, | |
482 const Matcher<Node*>& control_matcher) | |
483 : NodeMatcher(IrOpcode::kLoadElement), | |
484 access_matcher_(access_matcher), | |
485 base_matcher_(base_matcher), | |
486 index_matcher_(index_matcher), | |
487 length_matcher_(length_matcher), | |
488 effect_matcher_(effect_matcher), | |
489 control_matcher_(control_matcher) {} | |
490 | |
491 virtual void DescribeTo(std::ostream* os) const OVERRIDE { | |
492 NodeMatcher::DescribeTo(os); | |
493 *os << " whose access ("; | |
494 access_matcher_.DescribeTo(os); | |
495 *os << "), base ("; | |
496 base_matcher_.DescribeTo(os); | |
497 *os << "), index ("; | |
498 index_matcher_.DescribeTo(os); | |
499 *os << "), length ("; | |
500 length_matcher_.DescribeTo(os); | |
501 *os << "), effect ("; | |
502 effect_matcher_.DescribeTo(os); | |
503 *os << ") and control ("; | |
504 control_matcher_.DescribeTo(os); | |
505 *os << ")"; | |
506 } | |
507 | |
508 virtual bool MatchAndExplain(Node* node, | |
509 MatchResultListener* listener) const OVERRIDE { | |
510 return (NodeMatcher::MatchAndExplain(node, listener) && | |
511 PrintMatchAndExplain(OpParameter<ElementAccess>(node), "access", | |
512 access_matcher_, listener) && | |
513 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base", | |
514 base_matcher_, listener) && | |
515 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), | |
516 "index", index_matcher_, listener) && | |
517 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2), | |
518 "length", length_matcher_, listener) && | |
519 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", | |
520 effect_matcher_, listener) && | |
521 PrintMatchAndExplain(NodeProperties::GetControlInput(node), | |
522 "control", control_matcher_, listener)); | |
523 } | |
524 | |
525 private: | |
526 const Matcher<ElementAccess> access_matcher_; | |
527 const Matcher<Node*> base_matcher_; | |
528 const Matcher<Node*> index_matcher_; | |
529 const Matcher<Node*> length_matcher_; | |
530 const Matcher<Node*> effect_matcher_; | |
531 const Matcher<Node*> control_matcher_; | |
532 }; | |
533 | |
534 | |
535 class IsStoreElementMatcher FINAL : public NodeMatcher { | |
536 public: | |
537 IsStoreElementMatcher(const Matcher<ElementAccess>& access_matcher, | |
538 const Matcher<Node*>& base_matcher, | |
539 const Matcher<Node*>& index_matcher, | |
540 const Matcher<Node*>& length_matcher, | |
541 const Matcher<Node*>& value_matcher, | |
542 const Matcher<Node*>& effect_matcher, | |
543 const Matcher<Node*>& control_matcher) | |
544 : NodeMatcher(IrOpcode::kStoreElement), | |
545 access_matcher_(access_matcher), | |
546 base_matcher_(base_matcher), | |
547 index_matcher_(index_matcher), | |
548 length_matcher_(length_matcher), | |
549 value_matcher_(value_matcher), | |
550 effect_matcher_(effect_matcher), | |
551 control_matcher_(control_matcher) {} | |
552 | |
553 virtual void DescribeTo(std::ostream* os) const OVERRIDE { | |
554 NodeMatcher::DescribeTo(os); | |
555 *os << " whose access ("; | |
556 access_matcher_.DescribeTo(os); | |
557 *os << "), base ("; | |
558 base_matcher_.DescribeTo(os); | |
559 *os << "), index ("; | |
560 index_matcher_.DescribeTo(os); | |
561 *os << "), length ("; | |
562 length_matcher_.DescribeTo(os); | |
563 *os << "), value ("; | |
564 value_matcher_.DescribeTo(os); | |
565 *os << "), effect ("; | |
566 effect_matcher_.DescribeTo(os); | |
567 *os << ") and control ("; | |
568 control_matcher_.DescribeTo(os); | |
569 *os << ")"; | |
570 } | |
571 | |
572 virtual bool MatchAndExplain(Node* node, | |
573 MatchResultListener* listener) const OVERRIDE { | |
574 return (NodeMatcher::MatchAndExplain(node, listener) && | |
575 PrintMatchAndExplain(OpParameter<ElementAccess>(node), "access", | |
576 access_matcher_, listener) && | |
577 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base", | |
578 base_matcher_, listener) && | |
579 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), | |
580 "index", index_matcher_, listener) && | |
581 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2), | |
582 "length", length_matcher_, listener) && | |
583 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 3), | |
584 "value", value_matcher_, listener) && | |
585 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", | |
586 effect_matcher_, listener) && | |
587 PrintMatchAndExplain(NodeProperties::GetControlInput(node), | |
588 "control", control_matcher_, listener)); | |
589 } | |
590 | |
591 private: | |
592 const Matcher<ElementAccess> access_matcher_; | |
593 const Matcher<Node*> base_matcher_; | |
594 const Matcher<Node*> index_matcher_; | |
595 const Matcher<Node*> length_matcher_; | |
596 const Matcher<Node*> value_matcher_; | |
597 const Matcher<Node*> effect_matcher_; | |
598 const Matcher<Node*> control_matcher_; | |
599 }; | |
600 | |
601 | |
602 class IsLoadMatcher FINAL : public NodeMatcher { | |
603 public: | |
604 IsLoadMatcher(const Matcher<LoadRepresentation>& rep_matcher, | |
605 const Matcher<Node*>& base_matcher, | |
606 const Matcher<Node*>& index_matcher, | |
607 const Matcher<Node*>& effect_matcher, | |
608 const Matcher<Node*>& control_matcher) | |
609 : NodeMatcher(IrOpcode::kLoad), | |
610 rep_matcher_(rep_matcher), | |
611 base_matcher_(base_matcher), | |
612 index_matcher_(index_matcher), | |
613 effect_matcher_(effect_matcher), | |
614 control_matcher_(control_matcher) {} | |
615 | |
616 virtual void DescribeTo(std::ostream* os) const OVERRIDE { | |
617 NodeMatcher::DescribeTo(os); | |
618 *os << " whose rep ("; | |
619 rep_matcher_.DescribeTo(os); | |
620 *os << "), base ("; | |
621 base_matcher_.DescribeTo(os); | |
622 *os << "), index ("; | |
623 index_matcher_.DescribeTo(os); | |
624 *os << "), effect ("; | |
625 effect_matcher_.DescribeTo(os); | |
626 *os << ") and control ("; | |
627 control_matcher_.DescribeTo(os); | |
628 *os << ")"; | |
629 } | |
630 | |
631 virtual bool MatchAndExplain(Node* node, | |
632 MatchResultListener* listener) const OVERRIDE { | |
633 return (NodeMatcher::MatchAndExplain(node, listener) && | |
634 PrintMatchAndExplain(OpParameter<LoadRepresentation>(node), "rep", | |
635 rep_matcher_, listener) && | |
636 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base", | |
637 base_matcher_, listener) && | |
638 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), | |
639 "index", index_matcher_, listener) && | |
640 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", | |
641 effect_matcher_, listener) && | |
642 PrintMatchAndExplain(NodeProperties::GetControlInput(node), | |
643 "control", control_matcher_, listener)); | |
644 } | |
645 | |
646 private: | |
647 const Matcher<LoadRepresentation> rep_matcher_; | |
648 const Matcher<Node*> base_matcher_; | |
649 const Matcher<Node*> index_matcher_; | |
650 const Matcher<Node*> effect_matcher_; | |
651 const Matcher<Node*> control_matcher_; | |
652 }; | |
653 | |
654 | |
655 class IsStoreMatcher FINAL : public NodeMatcher { | |
656 public: | |
657 IsStoreMatcher(const Matcher<StoreRepresentation>& rep_matcher, | |
658 const Matcher<Node*>& base_matcher, | |
659 const Matcher<Node*>& index_matcher, | |
660 const Matcher<Node*>& value_matcher, | |
661 const Matcher<Node*>& effect_matcher, | |
662 const Matcher<Node*>& control_matcher) | |
663 : NodeMatcher(IrOpcode::kStore), | |
664 rep_matcher_(rep_matcher), | |
665 base_matcher_(base_matcher), | |
666 index_matcher_(index_matcher), | |
667 value_matcher_(value_matcher), | |
668 effect_matcher_(effect_matcher), | |
669 control_matcher_(control_matcher) {} | |
670 | |
671 virtual void DescribeTo(std::ostream* os) const OVERRIDE { | |
672 NodeMatcher::DescribeTo(os); | |
673 *os << " whose rep ("; | |
674 rep_matcher_.DescribeTo(os); | |
675 *os << "), base ("; | |
676 base_matcher_.DescribeTo(os); | |
677 *os << "), index ("; | |
678 index_matcher_.DescribeTo(os); | |
679 *os << "), value ("; | |
680 value_matcher_.DescribeTo(os); | |
681 *os << "), effect ("; | |
682 effect_matcher_.DescribeTo(os); | |
683 *os << ") and control ("; | |
684 control_matcher_.DescribeTo(os); | |
685 *os << ")"; | |
686 } | |
687 | |
688 virtual bool MatchAndExplain(Node* node, | |
689 MatchResultListener* listener) const OVERRIDE { | |
690 return (NodeMatcher::MatchAndExplain(node, listener) && | |
691 PrintMatchAndExplain(OpParameter<StoreRepresentation>(node), "rep", | |
692 rep_matcher_, listener) && | |
693 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base", | |
694 base_matcher_, listener) && | |
695 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), | |
696 "index", index_matcher_, listener) && | |
697 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2), | |
698 "value", value_matcher_, listener) && | |
699 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", | |
700 effect_matcher_, listener) && | |
701 PrintMatchAndExplain(NodeProperties::GetControlInput(node), | |
702 "control", control_matcher_, listener)); | |
703 } | |
704 | |
705 private: | |
706 const Matcher<StoreRepresentation> rep_matcher_; | |
707 const Matcher<Node*> base_matcher_; | |
708 const Matcher<Node*> index_matcher_; | |
709 const Matcher<Node*> value_matcher_; | |
710 const Matcher<Node*> effect_matcher_; | |
711 const Matcher<Node*> control_matcher_; | |
712 }; | |
713 | |
714 | |
715 class IsBinopMatcher FINAL : public NodeMatcher { | |
716 public: | |
717 IsBinopMatcher(IrOpcode::Value opcode, const Matcher<Node*>& lhs_matcher, | |
718 const Matcher<Node*>& rhs_matcher) | |
719 : NodeMatcher(opcode), | |
720 lhs_matcher_(lhs_matcher), | |
721 rhs_matcher_(rhs_matcher) {} | |
722 | |
723 virtual void DescribeTo(std::ostream* os) const OVERRIDE { | |
724 NodeMatcher::DescribeTo(os); | |
725 *os << " whose lhs ("; | |
726 lhs_matcher_.DescribeTo(os); | |
727 *os << ") and rhs ("; | |
728 rhs_matcher_.DescribeTo(os); | |
729 *os << ")"; | |
730 } | |
731 | |
732 virtual bool MatchAndExplain(Node* node, | |
733 MatchResultListener* listener) const OVERRIDE { | |
734 return (NodeMatcher::MatchAndExplain(node, listener) && | |
735 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "lhs", | |
736 lhs_matcher_, listener) && | |
737 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "rhs", | |
738 rhs_matcher_, listener)); | |
739 } | |
740 | |
741 private: | |
742 const Matcher<Node*> lhs_matcher_; | |
743 const Matcher<Node*> rhs_matcher_; | |
744 }; | |
745 | |
746 | |
747 class IsUnopMatcher FINAL : public NodeMatcher { | |
748 public: | |
749 IsUnopMatcher(IrOpcode::Value opcode, const Matcher<Node*>& input_matcher) | |
750 : NodeMatcher(opcode), input_matcher_(input_matcher) {} | |
751 | |
752 virtual void DescribeTo(std::ostream* os) const OVERRIDE { | |
753 NodeMatcher::DescribeTo(os); | |
754 *os << " whose input ("; | |
755 input_matcher_.DescribeTo(os); | |
756 *os << ")"; | |
757 } | |
758 | |
759 virtual bool MatchAndExplain(Node* node, | |
760 MatchResultListener* listener) const OVERRIDE { | |
761 return (NodeMatcher::MatchAndExplain(node, listener) && | |
762 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), | |
763 "input", input_matcher_, listener)); | |
764 } | |
765 | |
766 private: | |
767 const Matcher<Node*> input_matcher_; | |
768 }; | |
769 } | |
770 | |
771 | |
772 Matcher<Node*> IsBranch(const Matcher<Node*>& value_matcher, | |
773 const Matcher<Node*>& control_matcher) { | |
774 return MakeMatcher(new IsBranchMatcher(value_matcher, control_matcher)); | |
775 } | |
776 | |
777 | |
778 Matcher<Node*> IsMerge(const Matcher<Node*>& control0_matcher, | |
779 const Matcher<Node*>& control1_matcher) { | |
780 return MakeMatcher(new IsMergeMatcher(control0_matcher, control1_matcher)); | |
781 } | |
782 | |
783 | |
784 Matcher<Node*> IsIfTrue(const Matcher<Node*>& control_matcher) { | |
785 return MakeMatcher(new IsControl1Matcher(IrOpcode::kIfTrue, control_matcher)); | |
786 } | |
787 | |
788 | |
789 Matcher<Node*> IsIfFalse(const Matcher<Node*>& control_matcher) { | |
790 return MakeMatcher( | |
791 new IsControl1Matcher(IrOpcode::kIfFalse, control_matcher)); | |
792 } | |
793 | |
794 | |
795 Matcher<Node*> IsValueEffect(const Matcher<Node*>& value_matcher) { | |
796 return MakeMatcher(new IsUnopMatcher(IrOpcode::kValueEffect, value_matcher)); | |
797 } | |
798 | |
799 | |
800 Matcher<Node*> IsFinish(const Matcher<Node*>& value_matcher, | |
801 const Matcher<Node*>& effect_matcher) { | |
802 return MakeMatcher(new IsFinishMatcher(value_matcher, effect_matcher)); | |
803 } | |
804 | |
805 | |
806 Matcher<Node*> IsExternalConstant( | |
807 const Matcher<ExternalReference>& value_matcher) { | |
808 return MakeMatcher(new IsConstantMatcher<ExternalReference>( | |
809 IrOpcode::kExternalConstant, value_matcher)); | |
810 } | |
811 | |
812 | |
813 Matcher<Node*> IsHeapConstant( | |
814 const Matcher<Unique<HeapObject> >& value_matcher) { | |
815 return MakeMatcher(new IsConstantMatcher<Unique<HeapObject> >( | |
816 IrOpcode::kHeapConstant, value_matcher)); | |
817 } | |
818 | |
819 | |
820 Matcher<Node*> IsInt32Constant(const Matcher<int32_t>& value_matcher) { | |
821 return MakeMatcher( | |
822 new IsConstantMatcher<int32_t>(IrOpcode::kInt32Constant, value_matcher)); | |
823 } | |
824 | |
825 | |
826 Matcher<Node*> IsInt64Constant(const Matcher<int64_t>& value_matcher) { | |
827 return MakeMatcher( | |
828 new IsConstantMatcher<int64_t>(IrOpcode::kInt64Constant, value_matcher)); | |
829 } | |
830 | |
831 | |
832 Matcher<Node*> IsFloat32Constant(const Matcher<float>& value_matcher) { | |
833 return MakeMatcher( | |
834 new IsConstantMatcher<float>(IrOpcode::kFloat32Constant, value_matcher)); | |
835 } | |
836 | |
837 | |
838 Matcher<Node*> IsFloat64Constant(const Matcher<double>& value_matcher) { | |
839 return MakeMatcher( | |
840 new IsConstantMatcher<double>(IrOpcode::kFloat64Constant, value_matcher)); | |
841 } | |
842 | |
843 | |
844 Matcher<Node*> IsNumberConstant(const Matcher<double>& value_matcher) { | |
845 return MakeMatcher( | |
846 new IsConstantMatcher<double>(IrOpcode::kNumberConstant, value_matcher)); | |
847 } | |
848 | |
849 | |
850 Matcher<Node*> IsPhi(const Matcher<MachineType>& type_matcher, | |
851 const Matcher<Node*>& value0_matcher, | |
852 const Matcher<Node*>& value1_matcher, | |
853 const Matcher<Node*>& merge_matcher) { | |
854 return MakeMatcher(new IsPhiMatcher(type_matcher, value0_matcher, | |
855 value1_matcher, merge_matcher)); | |
856 } | |
857 | |
858 | |
859 Matcher<Node*> IsProjection(const Matcher<size_t>& index_matcher, | |
860 const Matcher<Node*>& base_matcher) { | |
861 return MakeMatcher(new IsProjectionMatcher(index_matcher, base_matcher)); | |
862 } | |
863 | |
864 | |
865 Matcher<Node*> IsCall(const Matcher<CallDescriptor*>& descriptor_matcher, | |
866 const Matcher<Node*>& value0_matcher, | |
867 const Matcher<Node*>& value1_matcher, | |
868 const Matcher<Node*>& value2_matcher, | |
869 const Matcher<Node*>& value3_matcher, | |
870 const Matcher<Node*>& effect_matcher, | |
871 const Matcher<Node*>& control_matcher) { | |
872 return MakeMatcher(new IsCallMatcher( | |
873 descriptor_matcher, value0_matcher, value1_matcher, value2_matcher, | |
874 value3_matcher, effect_matcher, control_matcher)); | |
875 } | |
876 | |
877 | |
878 Matcher<Node*> IsLoadField(const Matcher<FieldAccess>& access_matcher, | |
879 const Matcher<Node*>& base_matcher, | |
880 const Matcher<Node*>& effect_matcher) { | |
881 return MakeMatcher( | |
882 new IsLoadFieldMatcher(access_matcher, base_matcher, effect_matcher)); | |
883 } | |
884 | |
885 | |
886 Matcher<Node*> IsLoadElement(const Matcher<ElementAccess>& access_matcher, | |
887 const Matcher<Node*>& base_matcher, | |
888 const Matcher<Node*>& index_matcher, | |
889 const Matcher<Node*>& length_matcher, | |
890 const Matcher<Node*>& effect_matcher, | |
891 const Matcher<Node*>& control_matcher) { | |
892 return MakeMatcher(new IsLoadElementMatcher(access_matcher, base_matcher, | |
893 index_matcher, length_matcher, | |
894 effect_matcher, control_matcher)); | |
895 } | |
896 | |
897 | |
898 Matcher<Node*> IsStoreElement(const Matcher<ElementAccess>& access_matcher, | |
899 const Matcher<Node*>& base_matcher, | |
900 const Matcher<Node*>& index_matcher, | |
901 const Matcher<Node*>& length_matcher, | |
902 const Matcher<Node*>& value_matcher, | |
903 const Matcher<Node*>& effect_matcher, | |
904 const Matcher<Node*>& control_matcher) { | |
905 return MakeMatcher(new IsStoreElementMatcher( | |
906 access_matcher, base_matcher, index_matcher, length_matcher, | |
907 value_matcher, effect_matcher, control_matcher)); | |
908 } | |
909 | |
910 | |
911 Matcher<Node*> IsLoad(const Matcher<LoadRepresentation>& rep_matcher, | |
912 const Matcher<Node*>& base_matcher, | |
913 const Matcher<Node*>& index_matcher, | |
914 const Matcher<Node*>& effect_matcher, | |
915 const Matcher<Node*>& control_matcher) { | |
916 return MakeMatcher(new IsLoadMatcher(rep_matcher, base_matcher, index_matcher, | |
917 effect_matcher, control_matcher)); | |
918 } | |
919 | |
920 | |
921 Matcher<Node*> IsStore(const Matcher<StoreRepresentation>& rep_matcher, | |
922 const Matcher<Node*>& base_matcher, | |
923 const Matcher<Node*>& index_matcher, | |
924 const Matcher<Node*>& value_matcher, | |
925 const Matcher<Node*>& effect_matcher, | |
926 const Matcher<Node*>& control_matcher) { | |
927 return MakeMatcher(new IsStoreMatcher(rep_matcher, base_matcher, | |
928 index_matcher, value_matcher, | |
929 effect_matcher, control_matcher)); | |
930 } | |
931 | |
932 | |
933 #define IS_BINOP_MATCHER(Name) \ | |
934 Matcher<Node*> Is##Name(const Matcher<Node*>& lhs_matcher, \ | |
935 const Matcher<Node*>& rhs_matcher) { \ | |
936 return MakeMatcher( \ | |
937 new IsBinopMatcher(IrOpcode::k##Name, lhs_matcher, rhs_matcher)); \ | |
938 } | |
939 IS_BINOP_MATCHER(NumberLessThan) | |
940 IS_BINOP_MATCHER(NumberSubtract) | |
941 IS_BINOP_MATCHER(Word32And) | |
942 IS_BINOP_MATCHER(Word32Sar) | |
943 IS_BINOP_MATCHER(Word32Shl) | |
944 IS_BINOP_MATCHER(Word32Shr) | |
945 IS_BINOP_MATCHER(Word32Ror) | |
946 IS_BINOP_MATCHER(Word32Equal) | |
947 IS_BINOP_MATCHER(Word64And) | |
948 IS_BINOP_MATCHER(Word64Sar) | |
949 IS_BINOP_MATCHER(Word64Shl) | |
950 IS_BINOP_MATCHER(Word64Equal) | |
951 IS_BINOP_MATCHER(Int32AddWithOverflow) | |
952 IS_BINOP_MATCHER(Int32Add) | |
953 IS_BINOP_MATCHER(Int32Sub) | |
954 IS_BINOP_MATCHER(Int32Mul) | |
955 IS_BINOP_MATCHER(Int32MulHigh) | |
956 IS_BINOP_MATCHER(Int32LessThan) | |
957 IS_BINOP_MATCHER(Uint32LessThan) | |
958 IS_BINOP_MATCHER(Uint32LessThanOrEqual) | |
959 #undef IS_BINOP_MATCHER | |
960 | |
961 | |
962 #define IS_UNOP_MATCHER(Name) \ | |
963 Matcher<Node*> Is##Name(const Matcher<Node*>& input_matcher) { \ | |
964 return MakeMatcher(new IsUnopMatcher(IrOpcode::k##Name, input_matcher)); \ | |
965 } | |
966 IS_UNOP_MATCHER(ChangeFloat64ToInt32) | |
967 IS_UNOP_MATCHER(ChangeFloat64ToUint32) | |
968 IS_UNOP_MATCHER(ChangeInt32ToFloat64) | |
969 IS_UNOP_MATCHER(ChangeInt32ToInt64) | |
970 IS_UNOP_MATCHER(ChangeUint32ToFloat64) | |
971 IS_UNOP_MATCHER(ChangeUint32ToUint64) | |
972 IS_UNOP_MATCHER(TruncateFloat64ToFloat32) | |
973 IS_UNOP_MATCHER(TruncateFloat64ToInt32) | |
974 IS_UNOP_MATCHER(TruncateInt64ToInt32) | |
975 IS_UNOP_MATCHER(Float64Sqrt) | |
976 #undef IS_UNOP_MATCHER | |
977 | |
978 } // namespace compiler | 96 } // namespace compiler |
979 } // namespace internal | 97 } // namespace internal |
980 } // namespace v8 | 98 } // namespace v8 |
OLD | NEW |