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/compiler-unittests/graph-unittest.h" | 5 #include "test/compiler-unittests/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 | 10 |
11 using testing::MakeMatcher; | 11 using testing::MakeMatcher; |
12 using testing::MatcherInterface; | 12 using testing::MatcherInterface; |
13 using testing::MatchResultListener; | 13 using testing::MatchResultListener; |
14 using testing::StringMatchResultListener; | 14 using testing::StringMatchResultListener; |
15 | 15 |
16 namespace v8 { | 16 namespace v8 { |
17 namespace internal { | 17 namespace internal { |
18 | 18 |
19 // TODO(bmeurer): Find a new home for these functions. | 19 // TODO(bmeurer): Find a new home for these functions. |
20 template <typename T> | 20 template <typename T> |
21 inline std::ostream& operator<<(std::ostream& os, | 21 inline std::ostream& operator<<(std::ostream& os, |
22 const PrintableUnique<T>& value) { | 22 const PrintableUnique<T>& value) { |
23 return os << value.string(); | 23 return os << value.string(); |
24 } | 24 } |
| 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 } |
25 | 31 |
26 namespace compiler { | 32 namespace compiler { |
27 | 33 |
28 GraphTest::GraphTest(int num_parameters) : graph_(zone()) { | 34 GraphTest::GraphTest(int num_parameters) : graph_(zone()) { |
29 graph()->SetStart(graph()->NewNode(common()->Start(num_parameters))); | 35 graph()->SetStart(graph()->NewNode(common()->Start(num_parameters))); |
30 } | 36 } |
31 | 37 |
32 | 38 |
33 GraphTest::~GraphTest() {} | 39 GraphTest::~GraphTest() {} |
34 | 40 |
(...skipping 24 matching lines...) Expand all Loading... |
59 *os << "is a " << IrOpcode::Mnemonic(opcode_) << " node"; | 65 *os << "is a " << IrOpcode::Mnemonic(opcode_) << " node"; |
60 } | 66 } |
61 | 67 |
62 virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const | 68 virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const |
63 V8_OVERRIDE { | 69 V8_OVERRIDE { |
64 if (node == NULL) { | 70 if (node == NULL) { |
65 *listener << "which is NULL"; | 71 *listener << "which is NULL"; |
66 return false; | 72 return false; |
67 } | 73 } |
68 if (node->opcode() != opcode_) { | 74 if (node->opcode() != opcode_) { |
69 *listener << "whose opcode is " << IrOpcode::Mnemonic(node->opcode()); | 75 *listener << "whose opcode is " << IrOpcode::Mnemonic(node->opcode()) |
| 76 << " but should have been " << IrOpcode::Mnemonic(opcode_); |
70 return false; | 77 return false; |
71 } | 78 } |
72 return true; | 79 return true; |
73 } | 80 } |
74 | 81 |
75 private: | 82 private: |
76 const IrOpcode::Value opcode_; | 83 const IrOpcode::Value opcode_; |
77 }; | 84 }; |
78 | 85 |
79 | 86 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 PrintMatchAndExplain(NodeProperties::GetControlInput(node, 1), | 141 PrintMatchAndExplain(NodeProperties::GetControlInput(node, 1), |
135 "control1", control1_matcher_, listener)); | 142 "control1", control1_matcher_, listener)); |
136 } | 143 } |
137 | 144 |
138 private: | 145 private: |
139 const Matcher<Node*> control0_matcher_; | 146 const Matcher<Node*> control0_matcher_; |
140 const Matcher<Node*> control1_matcher_; | 147 const Matcher<Node*> control1_matcher_; |
141 }; | 148 }; |
142 | 149 |
143 | 150 |
144 class IsIfTrueMatcher V8_FINAL : public NodeMatcher { | 151 class IsControl1Matcher V8_FINAL : public NodeMatcher { |
145 public: | 152 public: |
146 explicit IsIfTrueMatcher(const Matcher<Node*>& control_matcher) | 153 IsControl1Matcher(IrOpcode::Value opcode, |
147 : NodeMatcher(IrOpcode::kIfTrue), control_matcher_(control_matcher) {} | 154 const Matcher<Node*>& control_matcher) |
| 155 : NodeMatcher(opcode), control_matcher_(control_matcher) {} |
148 | 156 |
149 virtual void DescribeTo(std::ostream* os) const V8_OVERRIDE { | 157 virtual void DescribeTo(std::ostream* os) const V8_OVERRIDE { |
150 NodeMatcher::DescribeTo(os); | 158 NodeMatcher::DescribeTo(os); |
151 *os << " whose control ("; | 159 *os << " whose control ("; |
152 control_matcher_.DescribeTo(os); | 160 control_matcher_.DescribeTo(os); |
153 *os << ")"; | 161 *os << ")"; |
154 } | 162 } |
155 | 163 |
156 virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const | 164 virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const |
157 V8_OVERRIDE { | 165 V8_OVERRIDE { |
158 return (NodeMatcher::MatchAndExplain(node, listener) && | 166 return (NodeMatcher::MatchAndExplain(node, listener) && |
159 PrintMatchAndExplain(NodeProperties::GetControlInput(node), | 167 PrintMatchAndExplain(NodeProperties::GetControlInput(node), |
160 "control", control_matcher_, listener)); | 168 "control", control_matcher_, listener)); |
161 } | 169 } |
162 | 170 |
163 private: | 171 private: |
164 const Matcher<Node*> control_matcher_; | 172 const Matcher<Node*> control_matcher_; |
165 }; | 173 }; |
166 | 174 |
167 | 175 |
168 class IsIfFalseMatcher V8_FINAL : public NodeMatcher { | 176 class IsFinishMatcher V8_FINAL : public NodeMatcher { |
169 public: | 177 public: |
170 explicit IsIfFalseMatcher(const Matcher<Node*>& control_matcher) | 178 IsFinishMatcher(const Matcher<Node*>& value_matcher, |
171 : NodeMatcher(IrOpcode::kIfFalse), control_matcher_(control_matcher) {} | 179 const Matcher<Node*>& effect_matcher) |
| 180 : NodeMatcher(IrOpcode::kFinish), |
| 181 value_matcher_(value_matcher), |
| 182 effect_matcher_(effect_matcher) {} |
172 | 183 |
173 virtual void DescribeTo(std::ostream* os) const V8_OVERRIDE { | 184 virtual void DescribeTo(std::ostream* os) const V8_OVERRIDE { |
174 NodeMatcher::DescribeTo(os); | 185 NodeMatcher::DescribeTo(os); |
175 *os << " whose control ("; | 186 *os << " whose value ("; |
176 control_matcher_.DescribeTo(os); | 187 value_matcher_.DescribeTo(os); |
| 188 *os << ") and effect ("; |
| 189 effect_matcher_.DescribeTo(os); |
177 *os << ")"; | 190 *os << ")"; |
178 } | 191 } |
179 | 192 |
180 virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const | 193 virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const |
181 V8_OVERRIDE { | 194 V8_OVERRIDE { |
182 return (NodeMatcher::MatchAndExplain(node, listener) && | 195 return (NodeMatcher::MatchAndExplain(node, listener) && |
183 PrintMatchAndExplain(NodeProperties::GetControlInput(node), | 196 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), |
184 "control", control_matcher_, listener)); | 197 "value", value_matcher_, listener) && |
| 198 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", |
| 199 effect_matcher_, listener)); |
185 } | 200 } |
186 | 201 |
187 private: | 202 private: |
188 const Matcher<Node*> control_matcher_; | 203 const Matcher<Node*> value_matcher_; |
| 204 const Matcher<Node*> effect_matcher_; |
189 }; | 205 }; |
190 | 206 |
191 | 207 |
192 template <typename T> | 208 template <typename T> |
193 class IsConstantMatcher V8_FINAL : public NodeMatcher { | 209 class IsConstantMatcher V8_FINAL : public NodeMatcher { |
194 public: | 210 public: |
195 IsConstantMatcher(IrOpcode::Value opcode, const Matcher<T>& value_matcher) | 211 IsConstantMatcher(IrOpcode::Value opcode, const Matcher<T>& value_matcher) |
196 : NodeMatcher(opcode), value_matcher_(value_matcher) {} | 212 : NodeMatcher(opcode), value_matcher_(value_matcher) {} |
197 | 213 |
198 virtual void DescribeTo(std::ostream* os) const V8_OVERRIDE { | 214 virtual void DescribeTo(std::ostream* os) const V8_OVERRIDE { |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
278 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base", | 294 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base", |
279 base_matcher_, listener)); | 295 base_matcher_, listener)); |
280 } | 296 } |
281 | 297 |
282 private: | 298 private: |
283 const Matcher<int32_t> index_matcher_; | 299 const Matcher<int32_t> index_matcher_; |
284 const Matcher<Node*> base_matcher_; | 300 const Matcher<Node*> base_matcher_; |
285 }; | 301 }; |
286 | 302 |
287 | 303 |
| 304 class IsCallMatcher V8_FINAL : public NodeMatcher { |
| 305 public: |
| 306 IsCallMatcher(const Matcher<CallDescriptor*>& descriptor_matcher, |
| 307 const Matcher<Node*>& value0_matcher, |
| 308 const Matcher<Node*>& value1_matcher, |
| 309 const Matcher<Node*>& value2_matcher, |
| 310 const Matcher<Node*>& value3_matcher, |
| 311 const Matcher<Node*>& effect_matcher, |
| 312 const Matcher<Node*>& control_matcher) |
| 313 : NodeMatcher(IrOpcode::kCall), |
| 314 descriptor_matcher_(descriptor_matcher), |
| 315 value0_matcher_(value0_matcher), |
| 316 value1_matcher_(value1_matcher), |
| 317 value2_matcher_(value2_matcher), |
| 318 value3_matcher_(value3_matcher), |
| 319 effect_matcher_(effect_matcher), |
| 320 control_matcher_(control_matcher) {} |
| 321 |
| 322 virtual void DescribeTo(std::ostream* os) const V8_OVERRIDE { |
| 323 NodeMatcher::DescribeTo(os); |
| 324 *os << " whose value0 ("; |
| 325 value0_matcher_.DescribeTo(os); |
| 326 *os << ") and value1 ("; |
| 327 value1_matcher_.DescribeTo(os); |
| 328 *os << ") and value2 ("; |
| 329 value2_matcher_.DescribeTo(os); |
| 330 *os << ") and value3 ("; |
| 331 value3_matcher_.DescribeTo(os); |
| 332 *os << ") and effect ("; |
| 333 effect_matcher_.DescribeTo(os); |
| 334 *os << ") and control ("; |
| 335 control_matcher_.DescribeTo(os); |
| 336 *os << ")"; |
| 337 } |
| 338 |
| 339 virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const |
| 340 V8_OVERRIDE { |
| 341 return (NodeMatcher::MatchAndExplain(node, listener) && |
| 342 PrintMatchAndExplain(OpParameter<CallDescriptor*>(node), |
| 343 "descriptor", descriptor_matcher_, listener) && |
| 344 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), |
| 345 "value0", value0_matcher_, listener) && |
| 346 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), |
| 347 "value1", value1_matcher_, listener) && |
| 348 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2), |
| 349 "value2", value2_matcher_, listener) && |
| 350 PrintMatchAndExplain(NodeProperties::GetValueInput(node, 3), |
| 351 "value3", value3_matcher_, listener) && |
| 352 PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", |
| 353 effect_matcher_, listener) && |
| 354 PrintMatchAndExplain(NodeProperties::GetControlInput(node), |
| 355 "control", control_matcher_, listener)); |
| 356 } |
| 357 |
| 358 private: |
| 359 const Matcher<CallDescriptor*> descriptor_matcher_; |
| 360 const Matcher<Node*> value0_matcher_; |
| 361 const Matcher<Node*> value1_matcher_; |
| 362 const Matcher<Node*> value2_matcher_; |
| 363 const Matcher<Node*> value3_matcher_; |
| 364 const Matcher<Node*> effect_matcher_; |
| 365 const Matcher<Node*> control_matcher_; |
| 366 }; |
| 367 |
| 368 |
288 class IsLoadMatcher V8_FINAL : public NodeMatcher { | 369 class IsLoadMatcher V8_FINAL : public NodeMatcher { |
289 public: | 370 public: |
290 IsLoadMatcher(const Matcher<MachineType>& type_matcher, | 371 IsLoadMatcher(const Matcher<MachineType>& type_matcher, |
291 const Matcher<Node*>& base_matcher, | 372 const Matcher<Node*>& base_matcher, |
292 const Matcher<Node*>& index_matcher, | 373 const Matcher<Node*>& index_matcher, |
293 const Matcher<Node*>& effect_matcher) | 374 const Matcher<Node*>& effect_matcher) |
294 : NodeMatcher(IrOpcode::kLoad), | 375 : NodeMatcher(IrOpcode::kLoad), |
295 type_matcher_(type_matcher), | 376 type_matcher_(type_matcher), |
296 base_matcher_(base_matcher), | 377 base_matcher_(base_matcher), |
297 index_matcher_(index_matcher), | 378 index_matcher_(index_matcher), |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
463 } | 544 } |
464 | 545 |
465 | 546 |
466 Matcher<Node*> IsMerge(const Matcher<Node*>& control0_matcher, | 547 Matcher<Node*> IsMerge(const Matcher<Node*>& control0_matcher, |
467 const Matcher<Node*>& control1_matcher) { | 548 const Matcher<Node*>& control1_matcher) { |
468 return MakeMatcher(new IsMergeMatcher(control0_matcher, control1_matcher)); | 549 return MakeMatcher(new IsMergeMatcher(control0_matcher, control1_matcher)); |
469 } | 550 } |
470 | 551 |
471 | 552 |
472 Matcher<Node*> IsIfTrue(const Matcher<Node*>& control_matcher) { | 553 Matcher<Node*> IsIfTrue(const Matcher<Node*>& control_matcher) { |
473 return MakeMatcher(new IsIfTrueMatcher(control_matcher)); | 554 return MakeMatcher(new IsControl1Matcher(IrOpcode::kIfTrue, control_matcher)); |
474 } | 555 } |
475 | 556 |
476 | 557 |
477 Matcher<Node*> IsIfFalse(const Matcher<Node*>& control_matcher) { | 558 Matcher<Node*> IsIfFalse(const Matcher<Node*>& control_matcher) { |
478 return MakeMatcher(new IsIfFalseMatcher(control_matcher)); | 559 return MakeMatcher( |
| 560 new IsControl1Matcher(IrOpcode::kIfFalse, control_matcher)); |
479 } | 561 } |
480 | 562 |
481 | 563 |
482 Matcher<Node*> IsInt32Constant(const Matcher<int32_t>& value_matcher) { | 564 Matcher<Node*> IsControlEffect(const Matcher<Node*>& control_matcher) { |
483 return MakeMatcher( | 565 return MakeMatcher( |
484 new IsConstantMatcher<int32_t>(IrOpcode::kInt32Constant, value_matcher)); | 566 new IsControl1Matcher(IrOpcode::kControlEffect, control_matcher)); |
485 } | 567 } |
486 | 568 |
487 | 569 |
| 570 Matcher<Node*> IsFinish(const Matcher<Node*>& value_matcher, |
| 571 const Matcher<Node*>& effect_matcher) { |
| 572 return MakeMatcher(new IsFinishMatcher(value_matcher, effect_matcher)); |
| 573 } |
| 574 |
| 575 |
| 576 Matcher<Node*> IsExternalConstant( |
| 577 const Matcher<ExternalReference>& value_matcher) { |
| 578 return MakeMatcher(new IsConstantMatcher<ExternalReference>( |
| 579 IrOpcode::kExternalConstant, value_matcher)); |
| 580 } |
| 581 |
| 582 |
488 Matcher<Node*> IsHeapConstant( | 583 Matcher<Node*> IsHeapConstant( |
489 const Matcher<PrintableUnique<HeapObject> >& value_matcher) { | 584 const Matcher<PrintableUnique<HeapObject> >& value_matcher) { |
490 return MakeMatcher(new IsConstantMatcher<PrintableUnique<HeapObject> >( | 585 return MakeMatcher(new IsConstantMatcher<PrintableUnique<HeapObject> >( |
491 IrOpcode::kHeapConstant, value_matcher)); | 586 IrOpcode::kHeapConstant, value_matcher)); |
492 } | 587 } |
493 | 588 |
494 | 589 |
| 590 Matcher<Node*> IsInt32Constant(const Matcher<int32_t>& value_matcher) { |
| 591 return MakeMatcher( |
| 592 new IsConstantMatcher<int32_t>(IrOpcode::kInt32Constant, value_matcher)); |
| 593 } |
| 594 |
| 595 |
| 596 Matcher<Node*> IsNumberConstant(const Matcher<double>& value_matcher) { |
| 597 return MakeMatcher( |
| 598 new IsConstantMatcher<double>(IrOpcode::kNumberConstant, value_matcher)); |
| 599 } |
| 600 |
| 601 |
495 Matcher<Node*> IsPhi(const Matcher<Node*>& value0_matcher, | 602 Matcher<Node*> IsPhi(const Matcher<Node*>& value0_matcher, |
496 const Matcher<Node*>& value1_matcher, | 603 const Matcher<Node*>& value1_matcher, |
497 const Matcher<Node*>& merge_matcher) { | 604 const Matcher<Node*>& merge_matcher) { |
498 return MakeMatcher( | 605 return MakeMatcher( |
499 new IsPhiMatcher(value0_matcher, value1_matcher, merge_matcher)); | 606 new IsPhiMatcher(value0_matcher, value1_matcher, merge_matcher)); |
500 } | 607 } |
501 | 608 |
502 | 609 |
503 Matcher<Node*> IsProjection(const Matcher<int32_t>& index_matcher, | 610 Matcher<Node*> IsProjection(const Matcher<int32_t>& index_matcher, |
504 const Matcher<Node*>& base_matcher) { | 611 const Matcher<Node*>& base_matcher) { |
505 return MakeMatcher(new IsProjectionMatcher(index_matcher, base_matcher)); | 612 return MakeMatcher(new IsProjectionMatcher(index_matcher, base_matcher)); |
506 } | 613 } |
507 | 614 |
508 | 615 |
| 616 Matcher<Node*> IsCall(const Matcher<CallDescriptor*>& descriptor_matcher, |
| 617 const Matcher<Node*>& value0_matcher, |
| 618 const Matcher<Node*>& value1_matcher, |
| 619 const Matcher<Node*>& value2_matcher, |
| 620 const Matcher<Node*>& value3_matcher, |
| 621 const Matcher<Node*>& effect_matcher, |
| 622 const Matcher<Node*>& control_matcher) { |
| 623 return MakeMatcher(new IsCallMatcher( |
| 624 descriptor_matcher, value0_matcher, value1_matcher, value2_matcher, |
| 625 value3_matcher, effect_matcher, control_matcher)); |
| 626 } |
| 627 |
| 628 |
509 Matcher<Node*> IsLoad(const Matcher<MachineType>& type_matcher, | 629 Matcher<Node*> IsLoad(const Matcher<MachineType>& type_matcher, |
510 const Matcher<Node*>& base_matcher, | 630 const Matcher<Node*>& base_matcher, |
511 const Matcher<Node*>& index_matcher, | 631 const Matcher<Node*>& index_matcher, |
512 const Matcher<Node*>& effect_matcher) { | 632 const Matcher<Node*>& effect_matcher) { |
513 return MakeMatcher(new IsLoadMatcher(type_matcher, base_matcher, | 633 return MakeMatcher(new IsLoadMatcher(type_matcher, base_matcher, |
514 index_matcher, effect_matcher)); | 634 index_matcher, effect_matcher)); |
515 } | 635 } |
516 | 636 |
517 | 637 |
518 Matcher<Node*> IsStore(const Matcher<MachineType>& type_matcher, | 638 Matcher<Node*> IsStore(const Matcher<MachineType>& type_matcher, |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
550 Matcher<Node*> Is##Name(const Matcher<Node*>& input_matcher) { \ | 670 Matcher<Node*> Is##Name(const Matcher<Node*>& input_matcher) { \ |
551 return MakeMatcher(new IsUnopMatcher(IrOpcode::k##Name, input_matcher)); \ | 671 return MakeMatcher(new IsUnopMatcher(IrOpcode::k##Name, input_matcher)); \ |
552 } | 672 } |
553 IS_UNOP_MATCHER(ConvertInt64ToInt32) | 673 IS_UNOP_MATCHER(ConvertInt64ToInt32) |
554 IS_UNOP_MATCHER(ChangeInt32ToFloat64) | 674 IS_UNOP_MATCHER(ChangeInt32ToFloat64) |
555 #undef IS_UNOP_MATCHER | 675 #undef IS_UNOP_MATCHER |
556 | 676 |
557 } // namespace compiler | 677 } // namespace compiler |
558 } // namespace internal | 678 } // namespace internal |
559 } // namespace v8 | 679 } // namespace v8 |
OLD | NEW |