Home | History | Annotate | Download | only in compiler
      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/coalesced-live-ranges.h"
      6 #include "test/unittests/compiler/live-range-builder.h"
      7 #include "test/unittests/test-utils.h"
      8 
      9 namespace v8 {
     10 namespace internal {
     11 namespace compiler {
     12 
     13 
     14 class CoalescedLiveRangesTest : public TestWithZone {
     15  public:
     16   CoalescedLiveRangesTest() : TestWithZone(), ranges_(zone()) {}
     17   bool HasNoConflicts(const LiveRange* range);
     18   bool ConflictsPreciselyWith(const LiveRange* range, int id);
     19   bool ConflictsPreciselyWith(const LiveRange* range, int id1, int id2);
     20 
     21   CoalescedLiveRanges& ranges() { return ranges_; }
     22   const CoalescedLiveRanges& ranges() const { return ranges_; }
     23   bool AllocationsAreValid() const;
     24   void RemoveConflicts(LiveRange* range);
     25 
     26  private:
     27   typedef ZoneSet<int> LiveRangeIDs;
     28   bool IsRangeConflictingWith(const LiveRange* range, const LiveRangeIDs& ids);
     29   CoalescedLiveRanges ranges_;
     30 };
     31 
     32 
     33 bool CoalescedLiveRangesTest::ConflictsPreciselyWith(const LiveRange* range,
     34                                                      int id) {
     35   LiveRangeIDs set(zone());
     36   set.insert(id);
     37   return IsRangeConflictingWith(range, set);
     38 }
     39 
     40 
     41 bool CoalescedLiveRangesTest::ConflictsPreciselyWith(const LiveRange* range,
     42                                                      int id1, int id2) {
     43   LiveRangeIDs set(zone());
     44   set.insert(id1);
     45   set.insert(id2);
     46   return IsRangeConflictingWith(range, set);
     47 }
     48 
     49 
     50 bool CoalescedLiveRangesTest::HasNoConflicts(const LiveRange* range) {
     51   LiveRangeIDs set(zone());
     52   return IsRangeConflictingWith(range, set);
     53 }
     54 
     55 
     56 void CoalescedLiveRangesTest::RemoveConflicts(LiveRange* range) {
     57   auto conflicts = ranges().GetConflicts(range);
     58   LiveRangeIDs seen(zone());
     59   for (auto c = conflicts.Current(); c != nullptr;
     60        c = conflicts.RemoveCurrentAndGetNext()) {
     61     int id = c->TopLevel()->vreg();
     62     EXPECT_FALSE(seen.count(id) > 0);
     63     seen.insert(c->TopLevel()->vreg());
     64   }
     65 }
     66 
     67 
     68 bool CoalescedLiveRangesTest::AllocationsAreValid() const {
     69   return ranges().VerifyAllocationsAreValidForTesting();
     70 }
     71 
     72 
     73 bool CoalescedLiveRangesTest::IsRangeConflictingWith(const LiveRange* range,
     74                                                      const LiveRangeIDs& ids) {
     75   LiveRangeIDs found_ids(zone());
     76 
     77   auto conflicts = ranges().GetConflicts(range);
     78   for (auto conflict = conflicts.Current(); conflict != nullptr;
     79        conflict = conflicts.GetNext()) {
     80     found_ids.insert(conflict->TopLevel()->vreg());
     81   }
     82   return found_ids == ids;
     83 }
     84 
     85 
     86 TEST_F(CoalescedLiveRangesTest, VisitEmptyAllocations) {
     87   LiveRange* range = TestRangeBuilder(zone()).Id(1).Build(1, 5);
     88   ASSERT_TRUE(ranges().empty());
     89   ASSERT_TRUE(AllocationsAreValid());
     90   ASSERT_TRUE(HasNoConflicts(range));
     91 }
     92 
     93 
     94 TEST_F(CoalescedLiveRangesTest, CandidateBeforeAfterAllocations) {
     95   LiveRange* range = TestRangeBuilder(zone()).Id(1).Build(5, 6);
     96   ranges().AllocateRange(range);
     97   ASSERT_FALSE(ranges().empty());
     98   ASSERT_TRUE(AllocationsAreValid());
     99   LiveRange* query = TestRangeBuilder(zone()).Id(2).Build(1, 2);
    100   ASSERT_TRUE(HasNoConflicts(query));
    101   query = TestRangeBuilder(zone()).Id(3).Build(1, 5);
    102   ASSERT_TRUE(HasNoConflicts(query));
    103 }
    104 
    105 
    106 TEST_F(CoalescedLiveRangesTest, CandidateBeforeAfterManyAllocations) {
    107   LiveRange* range =
    108       TestRangeBuilder(zone()).Id(1).Add(5, 7).Add(10, 12).Build();
    109   ranges().AllocateRange(range);
    110   ASSERT_FALSE(ranges().empty());
    111   ASSERT_TRUE(AllocationsAreValid());
    112   LiveRange* query =
    113       TestRangeBuilder(zone()).Id(2).Add(1, 2).Add(13, 15).Build();
    114   ASSERT_TRUE(HasNoConflicts(query));
    115   query = TestRangeBuilder(zone()).Id(3).Add(1, 5).Add(12, 15).Build();
    116   ASSERT_TRUE(HasNoConflicts(query));
    117 }
    118 
    119 
    120 TEST_F(CoalescedLiveRangesTest, SelfConflictsPreciselyWithSelf) {
    121   LiveRange* range = TestRangeBuilder(zone()).Id(1).Build(1, 5);
    122   ranges().AllocateRange(range);
    123   ASSERT_FALSE(ranges().empty());
    124   ASSERT_TRUE(AllocationsAreValid());
    125   ASSERT_TRUE(ConflictsPreciselyWith(range, 1));
    126   range = TestRangeBuilder(zone()).Id(2).Build(8, 10);
    127   ranges().AllocateRange(range);
    128   ASSERT_TRUE(ConflictsPreciselyWith(range, 2));
    129 }
    130 
    131 
    132 TEST_F(CoalescedLiveRangesTest, QueryStartsBeforeConflict) {
    133   LiveRange* range = TestRangeBuilder(zone()).Id(1).Build(2, 5);
    134   ranges().AllocateRange(range);
    135   LiveRange* query = TestRangeBuilder(zone()).Id(2).Build(1, 3);
    136   ASSERT_TRUE(ConflictsPreciselyWith(query, 1));
    137   range = TestRangeBuilder(zone()).Id(3).Build(8, 10);
    138   ranges().AllocateRange(range);
    139   query = TestRangeBuilder(zone()).Id(4).Build(6, 9);
    140   ASSERT_TRUE(ConflictsPreciselyWith(query, 3));
    141 }
    142 
    143 
    144 TEST_F(CoalescedLiveRangesTest, QueryStartsInConflict) {
    145   LiveRange* range = TestRangeBuilder(zone()).Id(1).Build(2, 5);
    146   ranges().AllocateRange(range);
    147   LiveRange* query = TestRangeBuilder(zone()).Id(2).Build(3, 6);
    148   ASSERT_TRUE(ConflictsPreciselyWith(query, 1));
    149   range = TestRangeBuilder(zone()).Id(3).Build(8, 10);
    150   ranges().AllocateRange(range);
    151   query = TestRangeBuilder(zone()).Id(4).Build(9, 11);
    152   ASSERT_TRUE(ConflictsPreciselyWith(query, 3));
    153 }
    154 
    155 
    156 TEST_F(CoalescedLiveRangesTest, QueryContainedInConflict) {
    157   LiveRange* range = TestRangeBuilder(zone()).Id(1).Build(1, 5);
    158   ranges().AllocateRange(range);
    159   LiveRange* query = TestRangeBuilder(zone()).Id(2).Build(2, 3);
    160   ASSERT_TRUE(ConflictsPreciselyWith(query, 1));
    161 }
    162 
    163 
    164 TEST_F(CoalescedLiveRangesTest, QueryContainsConflict) {
    165   LiveRange* range = TestRangeBuilder(zone()).Id(1).Build(2, 3);
    166   ranges().AllocateRange(range);
    167   LiveRange* query = TestRangeBuilder(zone()).Id(2).Build(1, 5);
    168   ASSERT_TRUE(ConflictsPreciselyWith(query, 1));
    169 }
    170 
    171 
    172 TEST_F(CoalescedLiveRangesTest, QueryCoversManyIntervalsSameRange) {
    173   LiveRange* range =
    174       TestRangeBuilder(zone()).Id(1).Add(1, 5).Add(7, 9).Add(20, 25).Build();
    175   ranges().AllocateRange(range);
    176   LiveRange* query = TestRangeBuilder(zone()).Id(2).Build(2, 8);
    177   ASSERT_TRUE(ConflictsPreciselyWith(query, 1));
    178 }
    179 
    180 
    181 TEST_F(CoalescedLiveRangesTest, QueryCoversManyIntervalsDifferentRanges) {
    182   LiveRange* range =
    183       TestRangeBuilder(zone()).Id(1).Add(1, 5).Add(20, 25).Build();
    184   ranges().AllocateRange(range);
    185   range = TestRangeBuilder(zone()).Id(2).Build(7, 10);
    186   ranges().AllocateRange(range);
    187   LiveRange* query = TestRangeBuilder(zone()).Id(3).Build(2, 22);
    188   ASSERT_TRUE(ConflictsPreciselyWith(query, 1, 2));
    189 }
    190 
    191 
    192 TEST_F(CoalescedLiveRangesTest, QueryFitsInGaps) {
    193   LiveRange* range =
    194       TestRangeBuilder(zone()).Id(1).Add(1, 5).Add(10, 15).Add(20, 25).Build();
    195   ranges().AllocateRange(range);
    196   LiveRange* query =
    197       TestRangeBuilder(zone()).Id(3).Add(5, 10).Add(16, 19).Add(27, 30).Build();
    198   ASSERT_TRUE(HasNoConflicts(query));
    199 }
    200 
    201 
    202 TEST_F(CoalescedLiveRangesTest, DeleteConflictBefore) {
    203   LiveRange* range = TestRangeBuilder(zone()).Id(1).Add(1, 4).Add(5, 6).Build();
    204   ranges().AllocateRange(range);
    205   range = TestRangeBuilder(zone()).Id(2).Build(40, 50);
    206   ranges().AllocateRange(range);
    207   LiveRange* query = TestRangeBuilder(zone()).Id(3).Build(3, 7);
    208   RemoveConflicts(query);
    209   query = TestRangeBuilder(zone()).Id(4).Build(0, 60);
    210   ASSERT_TRUE(ConflictsPreciselyWith(query, 2));
    211 }
    212 
    213 
    214 TEST_F(CoalescedLiveRangesTest, DeleteConflictAfter) {
    215   LiveRange* range = TestRangeBuilder(zone()).Id(1).Build(1, 5);
    216   ranges().AllocateRange(range);
    217   range = TestRangeBuilder(zone()).Id(2).Add(40, 50).Add(60, 70).Build();
    218   ranges().AllocateRange(range);
    219   LiveRange* query = TestRangeBuilder(zone()).Id(3).Build(45, 60);
    220   RemoveConflicts(query);
    221   query = TestRangeBuilder(zone()).Id(4).Build(0, 60);
    222   ASSERT_TRUE(ConflictsPreciselyWith(query, 1));
    223 }
    224 
    225 
    226 TEST_F(CoalescedLiveRangesTest, DeleteConflictStraddle) {
    227   LiveRange* range =
    228       TestRangeBuilder(zone()).Id(1).Add(1, 5).Add(10, 20).Build();
    229   ranges().AllocateRange(range);
    230   range = TestRangeBuilder(zone()).Id(2).Build(40, 50);
    231   ranges().AllocateRange(range);
    232   LiveRange* query = TestRangeBuilder(zone()).Id(3).Build(4, 15);
    233   RemoveConflicts(query);
    234   query = TestRangeBuilder(zone()).Id(4).Build(0, 60);
    235   ASSERT_TRUE(ConflictsPreciselyWith(query, 2));
    236 }
    237 
    238 
    239 TEST_F(CoalescedLiveRangesTest, DeleteConflictManyOverlapsBefore) {
    240   LiveRange* range =
    241       TestRangeBuilder(zone()).Id(1).Add(1, 5).Add(6, 10).Add(10, 20).Build();
    242   ranges().AllocateRange(range);
    243   range = TestRangeBuilder(zone()).Id(2).Build(40, 50);
    244   ranges().AllocateRange(range);
    245   LiveRange* query = TestRangeBuilder(zone()).Id(3).Build(4, 15);
    246   RemoveConflicts(query);
    247   query = TestRangeBuilder(zone()).Id(4).Build(0, 60);
    248   ASSERT_TRUE(ConflictsPreciselyWith(query, 2));
    249 }
    250 
    251 
    252 TEST_F(CoalescedLiveRangesTest, DeleteWhenConflictRepeatsAfterNonConflict) {
    253   LiveRange* range =
    254       TestRangeBuilder(zone()).Id(1).Add(1, 5).Add(6, 10).Add(20, 30).Build();
    255   ranges().AllocateRange(range);
    256   range = TestRangeBuilder(zone()).Id(2).Build(12, 15);
    257   ranges().AllocateRange(range);
    258   LiveRange* query =
    259       TestRangeBuilder(zone()).Id(3).Add(1, 8).Add(22, 25).Build();
    260   RemoveConflicts(query);
    261   query = TestRangeBuilder(zone()).Id(4).Build(0, 60);
    262   ASSERT_TRUE(ConflictsPreciselyWith(query, 2));
    263 }
    264 
    265 
    266 }  // namespace compiler
    267 }  // namespace internal
    268 }  // namespace v8
    269