// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.


#include "test/unittests/compiler/live-range-builder.h"
#include "test/unittests/test-utils.h"


// TODO(mtrofin): would we want to centralize this definition?
#ifdef DEBUG
#define V8_ASSERT_DEBUG_DEATH(statement, regex) \
  ASSERT_DEATH_IF_SUPPORTED(statement, regex)
#define DISABLE_IN_RELEASE(Name) Name

#else
#define V8_ASSERT_DEBUG_DEATH(statement, regex) statement
#define DISABLE_IN_RELEASE(Name) DISABLED_##Name
#endif  // DEBUG

namespace v8 {
namespace internal {
namespace compiler {

class LiveRangeUnitTest : public TestWithZone {
 public:
  // Split helper, to avoid int->LifetimePosition conversion nuisance.
  LiveRange* Split(LiveRange* range, int pos) {
    return range->SplitAt(LifetimePosition::FromInt(pos), zone());
  }


  TopLevelLiveRange* Splinter(TopLevelLiveRange* top, int start, int end,
                              int new_id = 0) {
    if (top->splinter() == nullptr) {
      TopLevelLiveRange* ret = new (zone())
          TopLevelLiveRange(new_id, MachineRepresentation::kTagged);
      top->SetSplinter(ret);
    }
    top->Splinter(LifetimePosition::FromInt(start),
                  LifetimePosition::FromInt(end), zone());
    return top->splinter();
  }

  // Ranges first and second match structurally.
  bool RangesMatch(LiveRange* first, LiveRange* second) {
    if (first->Start() != second->Start() || first->End() != second->End()) {
      return false;
    }
    UseInterval* i1 = first->first_interval();
    UseInterval* i2 = second->first_interval();

    while (i1 != nullptr && i2 != nullptr) {
      if (i1->start() != i2->start() || i1->end() != i2->end()) return false;
      i1 = i1->next();
      i2 = i2->next();
    }
    if (i1 != nullptr || i2 != nullptr) return false;

    UsePosition* p1 = first->first_pos();
    UsePosition* p2 = second->first_pos();

    while (p1 != nullptr && p2 != nullptr) {
      if (p1->pos() != p2->pos()) return false;
      p1 = p1->next();
      p2 = p2->next();
    }
    if (p1 != nullptr || p2 != nullptr) return false;
    return true;
  }
};


TEST_F(LiveRangeUnitTest, InvalidConstruction) {
  // Build a range manually, because the builder guards against empty cases.
  TopLevelLiveRange* range =
      new (zone()) TopLevelLiveRange(1, MachineRepresentation::kTagged);
  V8_ASSERT_DEBUG_DEATH(
      range->AddUseInterval(LifetimePosition::FromInt(0),
                            LifetimePosition::FromInt(0), zone()),
      ".*");
}


TEST_F(LiveRangeUnitTest, SplitInvalidStart) {
  TopLevelLiveRange* range = TestRangeBuilder(zone()).Build(0, 1);
  V8_ASSERT_DEBUG_DEATH(Split(range, 0), ".*");
}


TEST_F(LiveRangeUnitTest, DISABLE_IN_RELEASE(InvalidSplitEnd)) {
  TopLevelLiveRange* range = TestRangeBuilder(zone()).Build(0, 1);
  ASSERT_DEATH_IF_SUPPORTED(Split(range, 1), ".*");
}


TEST_F(LiveRangeUnitTest, DISABLE_IN_RELEASE(SplitInvalidPreStart)) {
  TopLevelLiveRange* range = TestRangeBuilder(zone()).Build(1, 2);
  ASSERT_DEATH_IF_SUPPORTED(Split(range, 0), ".*");
}


TEST_F(LiveRangeUnitTest, DISABLE_IN_RELEASE(SplitInvalidPostEnd)) {
  TopLevelLiveRange* range = TestRangeBuilder(zone()).Build(0, 1);
  ASSERT_DEATH_IF_SUPPORTED(Split(range, 2), ".*");
}


TEST_F(LiveRangeUnitTest, SplitSingleIntervalNoUsePositions) {
  TopLevelLiveRange* range = TestRangeBuilder(zone()).Build(0, 2);
  LiveRange* child = Split(range, 1);

  EXPECT_NE(nullptr, range->next());
  EXPECT_EQ(child, range->next());

  LiveRange* expected_top = TestRangeBuilder(zone()).Build(0, 1);
  LiveRange* expected_bottom = TestRangeBuilder(zone()).Build(1, 2);
  EXPECT_TRUE(RangesMatch(expected_top, range));
  EXPECT_TRUE(RangesMatch(expected_bottom, child));
}


TEST_F(LiveRangeUnitTest, SplitManyIntervalNoUsePositionsBetween) {
  TopLevelLiveRange* range =
      TestRangeBuilder(zone()).Add(0, 2).Add(4, 6).Build();
  LiveRange* child = Split(range, 3);

  EXPECT_NE(nullptr, range->next());
  EXPECT_EQ(child, range->next());

  LiveRange* expected_top = TestRangeBuilder(zone()).Build(0, 2);
  LiveRange* expected_bottom = TestRangeBuilder(zone()).Build(4, 6);
  EXPECT_TRUE(RangesMatch(expected_top, range));
  EXPECT_TRUE(RangesMatch(expected_bottom, child));
}


TEST_F(LiveRangeUnitTest, SplitManyIntervalNoUsePositionsFront) {
  TopLevelLiveRange* range =
      TestRangeBuilder(zone()).Add(0, 2).Add(4, 6).Build();
  LiveRange* child = Split(range, 1);

  EXPECT_NE(nullptr, range->next());
  EXPECT_EQ(child, range->next());

  LiveRange* expected_top = TestRangeBuilder(zone()).Build(0, 1);
  LiveRange* expected_bottom =
      TestRangeBuilder(zone()).Add(1, 2).Add(4, 6).Build();
  EXPECT_TRUE(RangesMatch(expected_top, range));
  EXPECT_TRUE(RangesMatch(expected_bottom, child));
}


TEST_F(LiveRangeUnitTest, SplitManyIntervalNoUsePositionsAfter) {
  TopLevelLiveRange* range =
      TestRangeBuilder(zone()).Add(0, 2).Add(4, 6).Build();
  LiveRange* child = Split(range, 5);

  EXPECT_NE(nullptr, range->next());
  EXPECT_EQ(child, range->next());

  LiveRange* expected_top =
      TestRangeBuilder(zone()).Add(0, 2).Add(4, 5).Build();
  LiveRange* expected_bottom = TestRangeBuilder(zone()).Build(5, 6);
  EXPECT_TRUE(RangesMatch(expected_top, range));
  EXPECT_TRUE(RangesMatch(expected_bottom, child));
}


TEST_F(LiveRangeUnitTest, SplitSingleIntervalUsePositions) {
  TopLevelLiveRange* range =
      TestRangeBuilder(zone()).Add(0, 3).AddUse(0).AddUse(2).Build();

  LiveRange* child = Split(range, 1);

  EXPECT_NE(nullptr, range->next());
  EXPECT_EQ(child, range->next());

  LiveRange* expected_top =
      TestRangeBuilder(zone()).Add(0, 1).AddUse(0).Build();
  LiveRange* expected_bottom =
      TestRangeBuilder(zone()).Add(1, 3).AddUse(2).Build();
  EXPECT_TRUE(RangesMatch(expected_top, range));
  EXPECT_TRUE(RangesMatch(expected_bottom, child));
}


TEST_F(LiveRangeUnitTest, SplitSingleIntervalUsePositionsAtPos) {
  TopLevelLiveRange* range =
      TestRangeBuilder(zone()).Add(0, 3).AddUse(0).AddUse(2).Build();

  LiveRange* child = Split(range, 2);

  EXPECT_NE(nullptr, range->next());
  EXPECT_EQ(child, range->next());

  LiveRange* expected_top =
      TestRangeBuilder(zone()).Add(0, 2).AddUse(0).AddUse(2).Build();
  LiveRange* expected_bottom = TestRangeBuilder(zone()).Build(2, 3);
  EXPECT_TRUE(RangesMatch(expected_top, range));
  EXPECT_TRUE(RangesMatch(expected_bottom, child));
}


TEST_F(LiveRangeUnitTest, SplitManyIntervalUsePositionsBetween) {
  TopLevelLiveRange* range =
      TestRangeBuilder(zone()).Add(0, 2).Add(4, 6).AddUse(1).AddUse(5).Build();
  LiveRange* child = Split(range, 3);

  EXPECT_NE(nullptr, range->next());
  EXPECT_EQ(child, range->next());

  LiveRange* expected_top =
      TestRangeBuilder(zone()).Add(0, 2).AddUse(1).Build();
  LiveRange* expected_bottom =
      TestRangeBuilder(zone()).Add(4, 6).AddUse(5).Build();
  EXPECT_TRUE(RangesMatch(expected_top, range));
  EXPECT_TRUE(RangesMatch(expected_bottom, child));
}


TEST_F(LiveRangeUnitTest, SplitManyIntervalUsePositionsAtInterval) {
  TopLevelLiveRange* range =
      TestRangeBuilder(zone()).Add(0, 2).Add(4, 6).AddUse(1).AddUse(4).Build();
  LiveRange* child = Split(range, 4);

  EXPECT_NE(nullptr, range->next());
  EXPECT_EQ(child, range->next());

  LiveRange* expected_top =
      TestRangeBuilder(zone()).Add(0, 2).AddUse(1).Build();
  LiveRange* expected_bottom =
      TestRangeBuilder(zone()).Add(4, 6).AddUse(4).Build();
  EXPECT_TRUE(RangesMatch(expected_top, range));
  EXPECT_TRUE(RangesMatch(expected_bottom, child));
}


TEST_F(LiveRangeUnitTest, SplitManyIntervalUsePositionsFront) {
  TopLevelLiveRange* range =
      TestRangeBuilder(zone()).Add(0, 2).Add(4, 6).AddUse(1).AddUse(5).Build();
  LiveRange* child = Split(range, 1);

  EXPECT_NE(nullptr, range->next());
  EXPECT_EQ(child, range->next());

  LiveRange* expected_top =
      TestRangeBuilder(zone()).Add(0, 1).AddUse(1).Build();
  LiveRange* expected_bottom =
      TestRangeBuilder(zone()).Add(1, 2).Add(4, 6).AddUse(5).Build();
  EXPECT_TRUE(RangesMatch(expected_top, range));
  EXPECT_TRUE(RangesMatch(expected_bottom, child));
}


TEST_F(LiveRangeUnitTest, SplitManyIntervalUsePositionsAfter) {
  TopLevelLiveRange* range =
      TestRangeBuilder(zone()).Add(0, 2).Add(4, 6).AddUse(1).AddUse(5).Build();
  LiveRange* child = Split(range, 5);

  EXPECT_NE(nullptr, range->next());
  EXPECT_EQ(child, range->next());

  LiveRange* expected_top =
      TestRangeBuilder(zone()).Add(0, 2).Add(4, 5).AddUse(1).AddUse(5).Build();
  LiveRange* expected_bottom = TestRangeBuilder(zone()).Build(5, 6);
  EXPECT_TRUE(RangesMatch(expected_top, range));
  EXPECT_TRUE(RangesMatch(expected_bottom, child));
}


TEST_F(LiveRangeUnitTest, SplinterSingleInterval) {
  TopLevelLiveRange* range = TestRangeBuilder(zone()).Build(0, 6);
  TopLevelLiveRange* splinter = Splinter(range, 3, 5);
  EXPECT_EQ(nullptr, range->next());
  EXPECT_EQ(nullptr, splinter->next());
  EXPECT_EQ(range, splinter->splintered_from());

  TopLevelLiveRange* expected_source =
      TestRangeBuilder(zone()).Add(0, 3).Add(5, 6).Build();
  TopLevelLiveRange* expected_splinter = TestRangeBuilder(zone()).Build(3, 5);
  EXPECT_TRUE(RangesMatch(expected_source, range));
  EXPECT_TRUE(RangesMatch(expected_splinter, splinter));
}


TEST_F(LiveRangeUnitTest, MergeSingleInterval) {
  TopLevelLiveRange* original = TestRangeBuilder(zone()).Build(0, 6);
  TopLevelLiveRange* splinter = Splinter(original, 3, 5);

  original->Merge(splinter, zone());
  TopLevelLiveRange* result = TestRangeBuilder(zone()).Build(0, 6);
  LiveRange* child_1 = Split(result, 3);
  Split(child_1, 5);

  EXPECT_TRUE(RangesMatch(result, original));
}


TEST_F(LiveRangeUnitTest, SplinterMultipleIntervalsOutside) {
  TopLevelLiveRange* range =
      TestRangeBuilder(zone()).Add(0, 3).Add(5, 8).Build();
  TopLevelLiveRange* splinter = Splinter(range, 2, 6);
  EXPECT_EQ(nullptr, range->next());
  EXPECT_EQ(nullptr, splinter->next());
  EXPECT_EQ(range, splinter->splintered_from());

  TopLevelLiveRange* expected_source =
      TestRangeBuilder(zone()).Add(0, 2).Add(6, 8).Build();
  TopLevelLiveRange* expected_splinter =
      TestRangeBuilder(zone()).Add(2, 3).Add(5, 6).Build();
  EXPECT_TRUE(RangesMatch(expected_source, range));
  EXPECT_TRUE(RangesMatch(expected_splinter, splinter));
}


TEST_F(LiveRangeUnitTest, MergeMultipleIntervalsOutside) {
  TopLevelLiveRange* original =
      TestRangeBuilder(zone()).Add(0, 3).Add(5, 8).Build();
  TopLevelLiveRange* splinter = Splinter(original, 2, 6);
  original->Merge(splinter, zone());

  TopLevelLiveRange* result =
      TestRangeBuilder(zone()).Add(0, 3).Add(5, 8).Build();
  LiveRange* child_1 = Split(result, 2);
  Split(child_1, 6);
  EXPECT_TRUE(RangesMatch(result, original));
}


TEST_F(LiveRangeUnitTest, SplinterMultipleIntervalsInside) {
  TopLevelLiveRange* range =
      TestRangeBuilder(zone()).Add(0, 3).Add(5, 8).Build();
  V8_ASSERT_DEBUG_DEATH(Splinter(range, 3, 5), ".*");
}


TEST_F(LiveRangeUnitTest, SplinterMultipleIntervalsLeft) {
  TopLevelLiveRange* range =
      TestRangeBuilder(zone()).Add(0, 3).Add(5, 8).Build();
  TopLevelLiveRange* splinter = Splinter(range, 2, 4);
  EXPECT_EQ(nullptr, range->next());
  EXPECT_EQ(nullptr, splinter->next());
  EXPECT_EQ(range, splinter->splintered_from());

  TopLevelLiveRange* expected_source =
      TestRangeBuilder(zone()).Add(0, 2).Add(5, 8).Build();
  TopLevelLiveRange* expected_splinter = TestRangeBuilder(zone()).Build(2, 3);
  EXPECT_TRUE(RangesMatch(expected_source, range));
  EXPECT_TRUE(RangesMatch(expected_splinter, splinter));
}


TEST_F(LiveRangeUnitTest, MergeMultipleIntervalsLeft) {
  TopLevelLiveRange* original =
      TestRangeBuilder(zone()).Add(0, 3).Add(5, 8).Build();
  TopLevelLiveRange* splinter = Splinter(original, 2, 4);
  original->Merge(splinter, zone());

  TopLevelLiveRange* result =
      TestRangeBuilder(zone()).Add(0, 3).Add(5, 8).Build();
  Split(result, 2);
  EXPECT_TRUE(RangesMatch(result, original));
}


TEST_F(LiveRangeUnitTest, SplinterMultipleIntervalsRight) {
  TopLevelLiveRange* range =
      TestRangeBuilder(zone()).Add(0, 3).Add(5, 8).Build();
  TopLevelLiveRange* splinter = Splinter(range, 4, 6);
  EXPECT_EQ(nullptr, range->next());
  EXPECT_EQ(nullptr, splinter->next());
  EXPECT_EQ(range, splinter->splintered_from());

  TopLevelLiveRange* expected_source =
      TestRangeBuilder(zone()).Add(0, 3).Add(6, 8).Build();
  TopLevelLiveRange* expected_splinter = TestRangeBuilder(zone()).Build(5, 6);
  EXPECT_TRUE(RangesMatch(expected_source, range));
  EXPECT_TRUE(RangesMatch(expected_splinter, splinter));
}


TEST_F(LiveRangeUnitTest, SplinterMergeMultipleTimes) {
  TopLevelLiveRange* range =
      TestRangeBuilder(zone()).Add(0, 3).Add(5, 10).Add(12, 16).Build();
  Splinter(range, 4, 6);
  Splinter(range, 8, 14);
  TopLevelLiveRange* splinter = range->splinter();
  EXPECT_EQ(nullptr, range->next());
  EXPECT_EQ(nullptr, splinter->next());
  EXPECT_EQ(range, splinter->splintered_from());

  TopLevelLiveRange* expected_source =
      TestRangeBuilder(zone()).Add(0, 3).Add(6, 8).Add(14, 16).Build();
  TopLevelLiveRange* expected_splinter =
      TestRangeBuilder(zone()).Add(5, 6).Add(8, 10).Add(12, 14).Build();
  EXPECT_TRUE(RangesMatch(expected_source, range));
  EXPECT_TRUE(RangesMatch(expected_splinter, splinter));
}


TEST_F(LiveRangeUnitTest, MergeMultipleIntervalsRight) {
  TopLevelLiveRange* original =
      TestRangeBuilder(zone()).Add(0, 3).Add(5, 8).Build();
  TopLevelLiveRange* splinter = Splinter(original, 4, 6);
  original->Merge(splinter, zone());

  TopLevelLiveRange* result =
      TestRangeBuilder(zone()).Add(0, 3).Add(5, 8).Build();
  LiveRange* child_1 = Split(result, 5);
  Split(child_1, 6);

  EXPECT_TRUE(RangesMatch(result, original));
}


TEST_F(LiveRangeUnitTest, MergeAfterSplitting) {
  TopLevelLiveRange* original = TestRangeBuilder(zone()).Build(0, 8);
  TopLevelLiveRange* splinter = Splinter(original, 4, 6);
  LiveRange* original_child = Split(original, 2);
  Split(original_child, 7);
  original->Merge(splinter, zone());

  TopLevelLiveRange* result = TestRangeBuilder(zone()).Build(0, 8);
  LiveRange* child_1 = Split(result, 2);
  LiveRange* child_2 = Split(child_1, 4);
  LiveRange* child_3 = Split(child_2, 6);
  Split(child_3, 7);

  EXPECT_TRUE(RangesMatch(result, original));
}


TEST_F(LiveRangeUnitTest, IDGeneration) {
  TopLevelLiveRange* vreg = TestRangeBuilder(zone()).Id(2).Build(0, 100);
  EXPECT_EQ(2, vreg->vreg());
  EXPECT_EQ(0, vreg->relative_id());

  TopLevelLiveRange* splinter =
      new (zone()) TopLevelLiveRange(101, MachineRepresentation::kTagged);
  vreg->SetSplinter(splinter);
  vreg->Splinter(LifetimePosition::FromInt(4), LifetimePosition::FromInt(12),
                 zone());

  EXPECT_EQ(101, splinter->vreg());
  EXPECT_EQ(1, splinter->relative_id());

  LiveRange* child = vreg->SplitAt(LifetimePosition::FromInt(50), zone());

  EXPECT_EQ(2, child->relative_id());

  LiveRange* splinter_child =
      splinter->SplitAt(LifetimePosition::FromInt(8), zone());

  EXPECT_EQ(1, splinter->relative_id());
  EXPECT_EQ(3, splinter_child->relative_id());

  vreg->Merge(splinter, zone());
  EXPECT_EQ(1, splinter->relative_id());
}

}  // namespace compiler
}  // namespace internal
}  // namespace v8
