| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/flow_graph_range_analysis.h" | 5 #include "vm/flow_graph_range_analysis.h" |
| 6 #include "vm/unit_test.h" | 6 #include "vm/unit_test.h" |
| 7 | 7 |
| 8 namespace dart { | 8 namespace dart { |
| 9 | 9 |
| 10 | 10 |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 254 Range* range_a = new Range(RangeBoundary::FromConstant(-1), | 254 Range* range_a = new Range(RangeBoundary::FromConstant(-1), |
| 255 RangeBoundary::PositiveInfinity()); | 255 RangeBoundary::PositiveInfinity()); |
| 256 range_a->Clamp(RangeBoundary::kRangeBoundaryInt64); | 256 range_a->Clamp(RangeBoundary::kRangeBoundaryInt64); |
| 257 EXPECT(range_a->min().ConstantValue() == -1); | 257 EXPECT(range_a->min().ConstantValue() == -1); |
| 258 EXPECT(range_a->max().ConstantValue() == RangeBoundary::kMax); | 258 EXPECT(range_a->max().ConstantValue() == RangeBoundary::kMax); |
| 259 Range* range_b = new Range(RangeBoundary::NegativeInfinity(), | 259 Range* range_b = new Range(RangeBoundary::NegativeInfinity(), |
| 260 RangeBoundary::FromConstant(1)); | 260 RangeBoundary::FromConstant(1)); |
| 261 range_b->Clamp(RangeBoundary::kRangeBoundaryInt64); | 261 range_b->Clamp(RangeBoundary::kRangeBoundaryInt64); |
| 262 EXPECT(range_b->min().ConstantValue() == RangeBoundary::kMin); | 262 EXPECT(range_b->min().ConstantValue() == RangeBoundary::kMin); |
| 263 EXPECT(range_b->max().ConstantValue() == 1); | 263 EXPECT(range_b->max().ConstantValue() == 1); |
| 264 | 264 Range* result = Range::BinaryOp(Token::kADD, |
| 265 { | 265 range_a, |
| 266 Range result; | 266 range_b, |
| 267 Range::BinaryOp(Token::kADD, | 267 NULL); |
| 268 range_a, | 268 ASSERT(result != NULL); |
| 269 range_b, | 269 EXPECT(result->min().IsNegativeInfinity()); |
| 270 NULL, | 270 EXPECT(result->max().IsPositiveInfinity()); |
| 271 &result); | |
| 272 ASSERT(!Range::IsUnknown(&result)); | |
| 273 EXPECT(result.min().IsNegativeInfinity()); | |
| 274 EXPECT(result.max().IsPositiveInfinity()); | |
| 275 } | |
| 276 | 271 |
| 277 // Test that [5, 10] + [0, 5] = [5, 15]. | 272 // Test that [5, 10] + [0, 5] = [5, 15]. |
| 278 Range* range_c = new Range(RangeBoundary::FromConstant(5), | 273 Range* range_c = new Range(RangeBoundary::FromConstant(5), |
| 279 RangeBoundary::FromConstant(10)); | 274 RangeBoundary::FromConstant(10)); |
| 280 Range* range_d = new Range(RangeBoundary::FromConstant(0), | 275 Range* range_d = new Range(RangeBoundary::FromConstant(0), |
| 281 RangeBoundary::FromConstant(5)); | 276 RangeBoundary::FromConstant(5)); |
| 277 result = Range::BinaryOp(Token::kADD, |
| 278 range_c, |
| 279 range_d, |
| 280 NULL); |
| 281 ASSERT(result != NULL); |
| 282 EXPECT(result->min().ConstantValue() == 5); |
| 283 EXPECT(result->max().ConstantValue() == 15); |
| 282 | 284 |
| 283 { | |
| 284 Range result; | |
| 285 Range::BinaryOp(Token::kADD, | |
| 286 range_c, | |
| 287 range_d, | |
| 288 NULL, | |
| 289 &result); | |
| 290 ASSERT(!Range::IsUnknown(&result)); | |
| 291 EXPECT(result.min().ConstantValue() == 5); | |
| 292 EXPECT(result.max().ConstantValue() == 15); | |
| 293 } | |
| 294 | 285 |
| 295 // Test that [0xff, 0xfff] & [0xf, 0xf] = [0x0, 0xf]. | 286 // Test that [0xff, 0xfff] & [0xf, 0xf] = [0x0, 0xf]. |
| 296 Range* range_e = new Range(RangeBoundary::FromConstant(0xff), | 287 Range* range_e = new Range(RangeBoundary::FromConstant(0xff), |
| 297 RangeBoundary::FromConstant(0xfff)); | 288 RangeBoundary::FromConstant(0xfff)); |
| 298 Range* range_f = new Range(RangeBoundary::FromConstant(0xf), | 289 Range* range_f = new Range(RangeBoundary::FromConstant(0xf), |
| 299 RangeBoundary::FromConstant(0xf)); | 290 RangeBoundary::FromConstant(0xf)); |
| 300 { | 291 result = Range::BinaryOp(Token::kBIT_AND, |
| 301 Range result; | 292 range_e, |
| 302 Range::BinaryOp(Token::kBIT_AND, | 293 range_f, |
| 303 range_e, | 294 NULL); |
| 304 range_f, | 295 ASSERT(result != NULL); |
| 305 NULL, | 296 EXPECT(result->min().ConstantValue() == 0x0); |
| 306 &result); | 297 EXPECT(result->max().ConstantValue() == 0xf); |
| 307 ASSERT(!Range::IsUnknown(&result)); | |
| 308 EXPECT(result.min().ConstantValue() == 0x0); | |
| 309 EXPECT(result.max().ConstantValue() == 0xf); | |
| 310 } | |
| 311 } | 298 } |
| 312 | 299 |
| 313 | 300 |
| 314 TEST_CASE(RangeAdd) { | 301 TEST_CASE(RangeAdd) { |
| 315 #define TEST_RANGE_ADD(l_min, l_max, r_min, r_max, result_min, result_max) \ | 302 #define TEST_RANGE_ADD(l_min, l_max, r_min, r_max, result_min, result_max) \ |
| 316 { \ | 303 { \ |
| 317 RangeBoundary min, max; \ | 304 RangeBoundary min, max; \ |
| 318 Range* left_range = new Range( \ | 305 Range* left_range = new Range( \ |
| 319 RangeBoundary::FromConstant(l_min), \ | 306 RangeBoundary::FromConstant(l_min), \ |
| 320 RangeBoundary::FromConstant(l_max)); \ | 307 RangeBoundary::FromConstant(l_max)); \ |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 531 static_cast<int64_t>(20), | 518 static_cast<int64_t>(20), |
| 532 static_cast<int64_t>(-20), | 519 static_cast<int64_t>(-20), |
| 533 static_cast<int64_t>(20), | 520 static_cast<int64_t>(20), |
| 534 RangeBoundary(), | 521 RangeBoundary(), |
| 535 RangeBoundary()); | 522 RangeBoundary()); |
| 536 | 523 |
| 537 #undef TEST_RANGE_AND | 524 #undef TEST_RANGE_AND |
| 538 } | 525 } |
| 539 | 526 |
| 540 | 527 |
| 541 TEST_CASE(RangeIntersectionMinMax) { | 528 TEST_CASE(RangeMinMax) { |
| 542 // Test IntersectionMin and IntersectionMax methods which for constants are | |
| 543 // simply defined as Max/Min respectively. | |
| 544 | |
| 545 // Constants. | 529 // Constants. |
| 546 // MIN(0, 1) == 0 | 530 // MIN(0, 1) == 0 |
| 547 EXPECT(RangeBoundary::IntersectionMax( | 531 EXPECT(RangeBoundary::Min( |
| 548 RangeBoundary::FromConstant(0), | 532 RangeBoundary::FromConstant(0), |
| 549 RangeBoundary::FromConstant(1)).ConstantValue() == 0); | 533 RangeBoundary::FromConstant(1), |
| 534 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == 0); |
| 550 // MIN(0, -1) == -1 | 535 // MIN(0, -1) == -1 |
| 551 EXPECT(RangeBoundary::IntersectionMax( | 536 EXPECT(RangeBoundary::Min( |
| 552 RangeBoundary::FromConstant(0), | 537 RangeBoundary::FromConstant(0), |
| 553 RangeBoundary::FromConstant(-1)).ConstantValue() == -1); | 538 RangeBoundary::FromConstant(-1), |
| 539 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == -1); |
| 554 | 540 |
| 555 // MIN(1, 0) == 0 | 541 // MIN(1, 0) == 0 |
| 556 EXPECT(RangeBoundary::IntersectionMax( | 542 EXPECT(RangeBoundary::Min( |
| 557 RangeBoundary::FromConstant(1), | 543 RangeBoundary::FromConstant(1), |
| 558 RangeBoundary::FromConstant(0)).ConstantValue() == 0); | 544 RangeBoundary::FromConstant(0), |
| 545 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == 0); |
| 559 // MIN(-1, 0) == -1 | 546 // MIN(-1, 0) == -1 |
| 560 EXPECT(RangeBoundary::IntersectionMax( | 547 EXPECT(RangeBoundary::Min( |
| 561 RangeBoundary::FromConstant(-1), | 548 RangeBoundary::FromConstant(-1), |
| 562 RangeBoundary::FromConstant(0)).ConstantValue() == -1); | 549 RangeBoundary::FromConstant(0), |
| 550 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == -1); |
| 563 | 551 |
| 564 // MAX(0, 1) == 1 | 552 // MAX(0, 1) == 1 |
| 565 EXPECT(RangeBoundary::IntersectionMin( | 553 EXPECT(RangeBoundary::Max( |
| 566 RangeBoundary::FromConstant(0), | 554 RangeBoundary::FromConstant(0), |
| 567 RangeBoundary::FromConstant(1)).ConstantValue() == 1); | 555 RangeBoundary::FromConstant(1), |
| 556 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == 1); |
| 568 | 557 |
| 569 // MAX(0, -1) == 0 | 558 // MAX(0, -1) == 0 |
| 570 EXPECT(RangeBoundary::IntersectionMin( | 559 EXPECT(RangeBoundary::Max( |
| 571 RangeBoundary::FromConstant(0), | 560 RangeBoundary::FromConstant(0), |
| 572 RangeBoundary::FromConstant(-1)).ConstantValue() == 0); | 561 RangeBoundary::FromConstant(-1), |
| 562 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == 0); |
| 573 | 563 |
| 574 // MAX(1, 0) == 1 | 564 // MAX(1, 0) == 1 |
| 575 EXPECT(RangeBoundary::IntersectionMin( | 565 EXPECT(RangeBoundary::Max( |
| 576 RangeBoundary::FromConstant(1), | 566 RangeBoundary::FromConstant(1), |
| 577 RangeBoundary::FromConstant(0)).ConstantValue() == 1); | 567 RangeBoundary::FromConstant(0), |
| 568 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == 1); |
| 578 // MAX(-1, 0) == 0 | 569 // MAX(-1, 0) == 0 |
| 579 EXPECT(RangeBoundary::IntersectionMin( | 570 EXPECT(RangeBoundary::Max( |
| 580 RangeBoundary::FromConstant(-1), | 571 RangeBoundary::FromConstant(-1), |
| 581 RangeBoundary::FromConstant(0)).ConstantValue() == 0); | 572 RangeBoundary::FromConstant(0), |
| 573 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == 0); |
| 582 | 574 |
| 583 RangeBoundary n_infinity = RangeBoundary::NegativeInfinity(); | 575 RangeBoundary n_infinity = RangeBoundary::NegativeInfinity(); |
| 584 RangeBoundary p_infinity = RangeBoundary::PositiveInfinity(); | 576 RangeBoundary p_infinity = RangeBoundary::PositiveInfinity(); |
| 585 | 577 |
| 586 // Constants vs. infinity. | 578 // Constants vs. infinity. |
| 587 EXPECT(RangeBoundary::IntersectionMin( | 579 EXPECT(RangeBoundary::Max( |
| 588 n_infinity, | 580 n_infinity, |
| 589 RangeBoundary::FromConstant(-1)).ConstantValue() == -1); | 581 RangeBoundary::FromConstant(-1), |
| 582 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == -1); |
| 590 | 583 |
| 591 EXPECT(RangeBoundary::IntersectionMin( | 584 EXPECT(RangeBoundary::Max( |
| 592 RangeBoundary::FromConstant(-1), | 585 RangeBoundary::FromConstant(-1), |
| 593 n_infinity).ConstantValue() == -1); | 586 n_infinity, |
| 587 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == -1); |
| 594 | 588 |
| 595 EXPECT(RangeBoundary::IntersectionMin( | 589 EXPECT(RangeBoundary::Max( |
| 596 RangeBoundary::FromConstant(1), | 590 RangeBoundary::FromConstant(1), |
| 597 n_infinity).ConstantValue() == 1); | 591 n_infinity, |
| 592 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == 1); |
| 598 | 593 |
| 599 EXPECT(RangeBoundary::IntersectionMin( | 594 EXPECT(RangeBoundary::Max( |
| 600 n_infinity, | 595 n_infinity, |
| 601 RangeBoundary::FromConstant(1)).ConstantValue() == 1); | 596 RangeBoundary::FromConstant(1), |
| 597 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == 1); |
| 602 | 598 |
| 603 EXPECT(RangeBoundary::IntersectionMax( | 599 EXPECT(RangeBoundary::Min( |
| 604 p_infinity, | 600 p_infinity, |
| 605 RangeBoundary::FromConstant(-1)).ConstantValue() == -1); | 601 RangeBoundary::FromConstant(-1), |
| 602 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == -1); |
| 606 | 603 |
| 607 EXPECT(RangeBoundary::IntersectionMax( | 604 EXPECT(RangeBoundary::Min( |
| 608 RangeBoundary::FromConstant(-1), | 605 RangeBoundary::FromConstant(-1), |
| 609 p_infinity).ConstantValue() == -1); | 606 p_infinity, |
| 607 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == -1); |
| 610 | 608 |
| 611 EXPECT(RangeBoundary::IntersectionMax( | 609 EXPECT(RangeBoundary::Min( |
| 612 RangeBoundary::FromConstant(1), | 610 RangeBoundary::FromConstant(1), |
| 613 p_infinity).ConstantValue() == 1); | 611 p_infinity, |
| 612 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == 1); |
| 614 | 613 |
| 615 EXPECT(RangeBoundary::IntersectionMax( | 614 EXPECT(RangeBoundary::Min( |
| 616 p_infinity, | 615 p_infinity, |
| 617 RangeBoundary::FromConstant(1)).ConstantValue() == 1); | 616 RangeBoundary::FromConstant(1), |
| 617 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == 1); |
| 618 |
| 619 // 64-bit values. |
| 620 EXPECT(RangeBoundary::Min( |
| 621 RangeBoundary(static_cast<int64_t>(kMinInt64)), |
| 622 RangeBoundary(static_cast<int64_t>(kMinInt32)), |
| 623 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == kMinInt64); |
| 624 |
| 625 EXPECT(RangeBoundary::Max( |
| 626 RangeBoundary(static_cast<int64_t>(kMinInt64)), |
| 627 RangeBoundary(static_cast<int64_t>(kMinInt32)), |
| 628 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == kMinInt32); |
| 629 |
| 630 EXPECT(RangeBoundary::Min( |
| 631 RangeBoundary(static_cast<int64_t>(kMaxInt64)), |
| 632 RangeBoundary(static_cast<int64_t>(kMaxInt32)), |
| 633 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == kMaxInt32); |
| 634 |
| 635 EXPECT(RangeBoundary::Max( |
| 636 RangeBoundary(static_cast<int64_t>(kMaxInt64)), |
| 637 RangeBoundary(static_cast<int64_t>(kMaxInt32)), |
| 638 RangeBoundary::kRangeBoundaryInt64).ConstantValue() == kMaxInt64); |
| 618 } | 639 } |
| 619 | 640 |
| 620 | 641 |
| 621 TEST_CASE(RangeJoinMinMax) { | |
| 622 // Test IntersectionMin and IntersectionMax methods which for constants are | |
| 623 // simply defined as Min/Max respectively. | |
| 624 | |
| 625 // Constants. | |
| 626 EXPECT(RangeBoundary::JoinMax( | |
| 627 RangeBoundary::FromConstant(0), | |
| 628 RangeBoundary::FromConstant(1)).ConstantValue() == 1); | |
| 629 EXPECT(RangeBoundary::JoinMax( | |
| 630 RangeBoundary::FromConstant(0), | |
| 631 RangeBoundary::FromConstant(-1)).ConstantValue() == 0); | |
| 632 EXPECT(RangeBoundary::JoinMax( | |
| 633 RangeBoundary::FromConstant(1), | |
| 634 RangeBoundary::FromConstant(0)).ConstantValue() == 1); | |
| 635 EXPECT(RangeBoundary::JoinMax( | |
| 636 RangeBoundary::FromConstant(-1), | |
| 637 RangeBoundary::FromConstant(0)).ConstantValue() == 0); | |
| 638 EXPECT(RangeBoundary::JoinMin( | |
| 639 RangeBoundary::FromConstant(0), | |
| 640 RangeBoundary::FromConstant(1)).ConstantValue() == 0); | |
| 641 EXPECT(RangeBoundary::JoinMin( | |
| 642 RangeBoundary::FromConstant(0), | |
| 643 RangeBoundary::FromConstant(-1)).ConstantValue() == -1); | |
| 644 EXPECT(RangeBoundary::JoinMin( | |
| 645 RangeBoundary::FromConstant(1), | |
| 646 RangeBoundary::FromConstant(0)).ConstantValue() == 0); | |
| 647 EXPECT(RangeBoundary::JoinMin( | |
| 648 RangeBoundary::FromConstant(-1), | |
| 649 RangeBoundary::FromConstant(0)).ConstantValue() == -1); | |
| 650 | |
| 651 RangeBoundary n_infinity = RangeBoundary::NegativeInfinity(); | |
| 652 RangeBoundary p_infinity = RangeBoundary::PositiveInfinity(); | |
| 653 | |
| 654 // Constants vs. infinity. | |
| 655 EXPECT(RangeBoundary::JoinMin( | |
| 656 n_infinity, | |
| 657 RangeBoundary::FromConstant(-1)).IsSmiMinimumOrBelow()); | |
| 658 | |
| 659 EXPECT(RangeBoundary::JoinMin( | |
| 660 RangeBoundary::FromConstant(-1), | |
| 661 n_infinity).IsSmiMinimumOrBelow()); | |
| 662 | |
| 663 EXPECT(RangeBoundary::JoinMin( | |
| 664 RangeBoundary::FromConstant(1), | |
| 665 n_infinity).IsSmiMinimumOrBelow()); | |
| 666 | |
| 667 EXPECT(RangeBoundary::JoinMin( | |
| 668 n_infinity, | |
| 669 RangeBoundary::FromConstant(1)).IsSmiMinimumOrBelow()); | |
| 670 | |
| 671 EXPECT(RangeBoundary::JoinMax( | |
| 672 p_infinity, | |
| 673 RangeBoundary::FromConstant(-1)).IsSmiMaximumOrAbove()); | |
| 674 | |
| 675 EXPECT(RangeBoundary::JoinMax( | |
| 676 RangeBoundary::FromConstant(-1), | |
| 677 p_infinity).IsSmiMaximumOrAbove()); | |
| 678 | |
| 679 EXPECT(RangeBoundary::JoinMax( | |
| 680 RangeBoundary::FromConstant(1), | |
| 681 p_infinity).IsSmiMaximumOrAbove()); | |
| 682 | |
| 683 EXPECT(RangeBoundary::JoinMax( | |
| 684 p_infinity, | |
| 685 RangeBoundary::FromConstant(1)).IsSmiMaximumOrAbove()); | |
| 686 } | |
| 687 | |
| 688 } // namespace dart | 642 } // namespace dart |
| OLD | NEW |