@Test
 public void getBasicIntervalReturnsAnIntervalIfOneMatches() {
   CompoundInterval ci = createCompoundIntervalWithoutRegister();
   BasicInterval bi = ci.getBasicInterval(DEFAULT_END);
   assertThat(bi.getBegin(), is(DEFAULT_BEGIN));
   assertThat(bi.getEnd(), is(DEFAULT_END));
 }
 @Test
 public void getBasicIntervalReturnsIntervalWithGreatestStartIfMultipleMatch() {
   CompoundInterval ci = new CompoundInterval(DEFAULT_BEGIN, DEFAULT_END, null);
   ci.add(new BasicInterval(DEFAULT_BEGIN, DEFAULT_END + 1));
   BasicInterval bi = ci.getBasicInterval(DEFAULT_END);
   assertThat(bi.getBegin(), is(DEFAULT_BEGIN));
   assertThat(bi.getEnd(), is(DEFAULT_END + 1));
 }
 @Test
 public void tailSetInclusiveIncludesIntervalWithLowerBound() {
   CompoundInterval ci = createCompoundIntervalWithoutRegister();
   ci.add(new MappedBasicInterval(DEFAULT_END + 1, DEFAULT_END + 2, null));
   ci.add(new MappedBasicInterval(DEFAULT_END + 2, DEFAULT_END + 3, null));
   BasicInterval lowerBound = new BasicInterval(DEFAULT_BEGIN, DEFAULT_END);
   assertThat(ci.tailSetInclusive(DEFAULT_BEGIN).contains(lowerBound), is(true));
 }
 @Test
 public void headSetInclusiveIncludesIntervalWithUpperBound() {
   CompoundInterval ci = createCompoundIntervalWithoutRegister();
   ci.add(new MappedBasicInterval(DEFAULT_END + 1, DEFAULT_END + 2, null));
   ci.add(new MappedBasicInterval(DEFAULT_END + 2, DEFAULT_END + 3, null));
   BasicInterval upperBound = new BasicInterval(DEFAULT_END + 2, DEFAULT_END + 3);
   assertThat(ci.headSetInclusive(DEFAULT_END + 3).contains(upperBound), is(true));
 }
 @Test
 public void intervalsDoNotIntersectWhenContainedIntervalsDoNotIntersectOtherWayRound() {
   CompoundInterval ci = new CompoundInterval(DEFAULT_END, DEFAULT_END + 1, null);
   ci.add(new MappedBasicInterval(DEFAULT_END + 1, DEFAULT_END + 2, null));
   ci.add(new MappedBasicInterval(DEFAULT_END + 3, DEFAULT_END + 4, null));
   CompoundInterval other = new CompoundInterval(1, DEFAULT_END, null);
   other.add(new MappedBasicInterval(DEFAULT_END + 2, DEFAULT_END + 3, null));
   other.add(new MappedBasicInterval(DEFAULT_END + 5, DEFAULT_END + 7, null));
   assertThat(ci.intersects(other), is(false));
 }
 @Test
 public void getBasicIntervalRegAllocStateReturnsNullIfNoMatchingIntervalIsFound() {
   CompoundInterval ci = createCompoundIntervalWithoutRegister();
   RegisterAllocatorState regAllocState = new RegisterAllocatorState(1);
   regAllocState.initializeDepthFirstNumbering(20);
   Instruction writeFloor = Empty.create(WRITE_FLOOR);
   regAllocState.setDFN(writeFloor, DEFAULT_BEGIN);
   ci.getBasicInterval(regAllocState, writeFloor);
   assertNull(ci.getBasicInterval(10));
 }
 @Test
 public void getBasicIntervalRegAllocStateReturnsAnIntervalIfOneMatches() {
   CompoundInterval ci = createCompoundIntervalWithoutRegister();
   RegisterAllocatorState regAllocState = new RegisterAllocatorState(1);
   regAllocState.initializeDepthFirstNumbering(20);
   Instruction writeFloor = Empty.create(WRITE_FLOOR);
   regAllocState.setDFN(writeFloor, DEFAULT_END);
   BasicInterval bi = ci.getBasicInterval(regAllocState, writeFloor);
   assertThat(bi.getBegin(), is(DEFAULT_BEGIN));
   assertThat(bi.getEnd(), is(DEFAULT_END));
 }
 @Test
 public void copyMethodsReallyReturnCopies() {
   BasicInterval bi = new BasicInterval(DEFAULT_BEGIN, DEFAULT_END);
   CompoundInterval toCopy = new CompoundInterval(bi, null);
   BasicInterval bi2 = new BasicInterval(DEFAULT_END, DEFAULT_END + 1);
   toCopy.add(bi2);
   CompoundInterval aCopy = toCopy.copy(new Register(1));
   assertThat(aCopy, not(sameInstance(toCopy)));
   CompoundInterval anotherCopy = toCopy.copy(new Register(3), bi);
   assertThat(anotherCopy, not(sameInstance(toCopy)));
 }
 @Test
 public void spillingOfCompoundIntervalSetsTheSpillInterval() {
   Register r = new Register(0);
   CompoundInterval ci = new CompoundInterval(DEFAULT_BEGIN, DEFAULT_END, r);
   RegisterAllocatorState regAllocState = new RegisterAllocatorState(1);
   assertThat(ci.isSpilled(regAllocState), is(false));
   ci.spill(new MockSpillLocationManager(), regAllocState);
   assertThat(ci.getSpillInterval().getOffset(), is(SPILL_INTERVAL_OFFSET));
   assertThat(ci.getSpillInterval().getSize(), is(SPILL_INTERVAL_SIZE));
   assertThat(ci.isSpilled(regAllocState), is(true));
 }
 @Test
 public void getBasicIntervalRegAllocStateReturnsIntervalWithGreatestStartIfMultipleMatch() {
   CompoundInterval ci = new CompoundInterval(DEFAULT_BEGIN, DEFAULT_END, null);
   ci.add(new BasicInterval(DEFAULT_BEGIN, DEFAULT_END + 1));
   RegisterAllocatorState regAllocState = new RegisterAllocatorState(1);
   regAllocState.initializeDepthFirstNumbering(20);
   Instruction writeFloor = Empty.create(WRITE_FLOOR);
   regAllocState.setDFN(writeFloor, DEFAULT_END);
   BasicInterval bi = ci.getBasicInterval(regAllocState, writeFloor);
   assertThat(bi.getBegin(), is(DEFAULT_BEGIN));
   assertThat(bi.getEnd(), is(DEFAULT_END + 1));
 }
 @Test
 public void addRangeCreatesNewIntervalWhenThereIsAGapBetweenRanges() {
   Register reg = new Register(3);
   CompoundInterval ci = new CompoundInterval(DEFAULT_BEGIN, DEFAULT_END, reg);
   assertThat(ci.last().getEnd(), is(DEFAULT_END));
   RegisterAllocatorState regAllocState = new RegisterAllocatorState(1);
   LiveIntervalElement live = new LiveIntervalElement(reg, null, null);
   ControlFlowGraph emptyCfg = new ControlFlowGraph(0);
   BasicBlock bb = new BasicBlock(1, null, emptyCfg);
   regAllocState.initializeDepthFirstNumbering(10);
   regAllocState.setDFN(bb.firstInstruction(), DEFAULT_END + 2);
   regAllocState.setDFN(bb.lastInstruction(), DEFAULT_END + 3);
   BasicInterval bi = ci.addRange(regAllocState, live, bb);
   assertThat(ci.last(), sameInstance(bi));
 }
 @Test
 public void addRangeChangesEndOfLastIntervalWhenRangesDirectlyFollowEachOther_NoDefUse() {
   Register reg = new Register(3);
   CompoundInterval ci = new CompoundInterval(DEFAULT_BEGIN, DEFAULT_END, reg);
   assertThat(ci.last().getEnd(), is(DEFAULT_END));
   RegisterAllocatorState regAllocState = new RegisterAllocatorState(1);
   LiveIntervalElement live = new LiveIntervalElement(reg, null, null);
   ControlFlowGraph emptyCfg = new ControlFlowGraph(0);
   BasicBlock bb = new BasicBlock(1, null, emptyCfg);
   regAllocState.initializeDepthFirstNumbering(10);
   regAllocState.setDFN(bb.firstInstruction(), DEFAULT_END);
   regAllocState.setDFN(bb.lastInstruction(), DEFAULT_END + 1);
   BasicInterval bi = ci.addRange(regAllocState, live, bb);
   assertNull(bi);
   assertThat(ci.last().getEnd(), is(DEFAULT_END + 1));
 }
 @Test
 public void addNonIntersectingStopIntervalNeedNotBeInIntervalThatsMerged() {
   CompoundInterval ci = createCompoundIntervalWithoutRegister();
   CompoundInterval toMerge = new CompoundInterval(DEFAULT_END + 1, DEFAULT_END + 2, null);
   BasicInterval otherInterval = new BasicInterval(DEFAULT_END + 1, DEFAULT_END + 3);
   toMerge.add(otherInterval);
   BasicInterval otherInterval2 = new BasicInterval(DEFAULT_END + 2, DEFAULT_END + 4);
   toMerge.add(otherInterval2);
   BasicInterval stop = new BasicInterval(DEFAULT_END + 1, DEFAULT_END + 4);
   ci.addNonIntersectingInterval(toMerge, stop);
   assertThat(ci.size(), is(3));
   assertThat(ci.getLowerBound(), is(DEFAULT_BEGIN));
   assertThat(ci.getUpperBound(), is(DEFAULT_END + 3));
 }
 @Test
 public void addNonIntersectingSetAddsAllIntervalsInTheOtherCompoundInterval() {
   CompoundInterval ci = createCompoundIntervalWithoutRegister();
   CompoundInterval toMerge = new CompoundInterval(DEFAULT_END + 1, DEFAULT_END + 2, null);
   BasicInterval otherInterval = new BasicInterval(DEFAULT_END + 1, DEFAULT_END + 3);
   toMerge.add(otherInterval);
   BasicInterval otherInterval2 = new BasicInterval(DEFAULT_END + 2, DEFAULT_END + 4);
   toMerge.add(otherInterval2);
   BasicInterval stop = new BasicInterval(DEFAULT_END + 5, DEFAULT_END + 6);
   ci.addNonIntersectingInterval(toMerge, stop);
   assertThat(ci.size(), is(4));
   assertThat(ci.getLowerBound(), is(DEFAULT_BEGIN));
   assertThat(ci.getUpperBound(), is(DEFAULT_END + 4));
 }
 @Test
 public void copyCopiesAllIntervalsToNewCompoundIntervalWithRightRegister() {
   BasicInterval bi = new BasicInterval(DEFAULT_BEGIN, DEFAULT_END);
   CompoundInterval toCopy = new CompoundInterval(bi, null);
   BasicInterval bi2 = new BasicInterval(DEFAULT_END, DEFAULT_END + 1);
   BasicInterval bi3 = new BasicInterval(DEFAULT_END + 1, DEFAULT_END + 2);
   toCopy.add(bi2);
   toCopy.add(bi3);
   Register r = new Register(2);
   CompoundInterval copy = toCopy.copy(r);
   assertThat(copy.getRegister(), is(r));
   assertThat(copy.contains(bi), is(true));
   assertThat(copy.contains(bi2), is(true));
   assertThat(copy.contains(bi3), is(true));
   assertThat(copy.size(), is(3));
 }
 @Test
 public void copyStopsAtTheRightPointWhenRequired() {
   BasicInterval bi = new BasicInterval(DEFAULT_BEGIN, DEFAULT_END);
   CompoundInterval toCopy = new CompoundInterval(bi, null);
   BasicInterval bi2 = new BasicInterval(DEFAULT_END, DEFAULT_END + 1);
   BasicInterval bi3 = new BasicInterval(DEFAULT_END + 1, DEFAULT_END + 2);
   toCopy.add(bi2);
   toCopy.add(bi3);
   Register r = new Register(2);
   CompoundInterval copy = toCopy.copy(r, bi2);
   assertThat(copy.getRegister(), is(r));
   assertThat(copy.contains(bi), is(true));
   assertThat(copy.contains(bi2), is(true));
   assertThat(copy.contains(bi3), is(false));
   assertThat(copy.size(), is(2));
 }
 @Test
 public void removeIntervalsAndCacheDoesNothingWhenOtherIntervalsIsEmpty() {
   CompoundInterval ci = createCompoundIntervalWithoutRegister();
   ci.add(new MappedBasicInterval(DEFAULT_END + 1, DEFAULT_END + 2, null));
   ci.add(new MappedBasicInterval(DEFAULT_END + 2, DEFAULT_END + 3, null));
   CompoundInterval cached = ci.removeIntervalsAndCache(new CompoundInterval(null));
   assertThat(ci.size(), is(3));
   assertThat(cached.isEmpty(), is(true));
 }
 @Test
 public void assignCausesAssignmentOfTheIntervalsRegisterToTheGivenRegister() {
   Register r = new Register(0);
   CompoundInterval ci = new CompoundInterval(DEFAULT_BEGIN, DEFAULT_END, r);
   Register s = new Register(1);
   RegisterAllocatorState regAllocState = new RegisterAllocatorState(0);
   assertThat(ci.isAssigned(regAllocState), is(false));
   assertNull(ci.getAssignment(regAllocState));
   ci.assign(s);
   assertThat(s.mapsToRegister, is(r));
   assertThat(!s.isSpilled() && s.isTouched() && s.isAllocated(), is(true));
   assertThat(r.mapsToRegister, is(s));
   assertThat(!r.isSpilled() && r.isTouched() && r.isAllocated(), is(true));
   assertThat(ci.isAssigned(regAllocState), is(true));
   assertThat(ci.getAssignment(regAllocState), is(s));
 }
 @Test
 public void nonEmptyCompoundIntervalsIntersectWithThemselves() {
   CompoundInterval ci = createCompoundIntervalWithoutRegister();
   assertThat(ci.intersects(ci), is(true));
 }
 @Test
 public void compoundIntervalsDoNotHaveASpillIntervalByDefault() {
   CompoundInterval ci = createCompoundIntervalWithoutRegister();
   assertNull(ci.getSpillInterval());
 }
 @Test
 public void getBasicIntervalReturnsNullIfNoMatchingIntervalIsFound() {
   CompoundInterval ci = createCompoundIntervalWithoutRegister();
   assertNull(ci.getBasicInterval(10));
 }
 @Test
 public void compoundIntervalsCanBeMadeFrequent() {
   CompoundInterval ci = createCompoundIntervalWithoutRegister();
   ci.setFrequent();
   assertThat(ci.isInfrequent(), is(false));
 }
 @Test
 public void registersDoNotMatterForIntersection() {
   CompoundInterval ci = new CompoundInterval(DEFAULT_BEGIN, DEFAULT_END, new Register(-1));
   CompoundInterval otherCi = new CompoundInterval(DEFAULT_BEGIN, DEFAULT_END, new Register(-2));
   assertThat(ci.intersects(otherCi), is(true));
 }
 @Test
 public void intervalsDoNotIntersectWhenFirstIntervalIsHigherThanTheOther() {
   CompoundInterval ci = new CompoundInterval(DEFAULT_END + 4, DEFAULT_END + 6, null);
   CompoundInterval other = createCompoundIntervalWithoutRegister();
   assertThat(ci.intersects(other), is(false));
 }
 @Test
 public void compoundIntervalsAreInfrequentByDefault() {
   CompoundInterval ci = createCompoundIntervalWithoutRegister();
   assertThat(ci.isInfrequent(), is(true));
 }
 @Test
 public void compoundIntervalsDoNotIntersectWithEmptyIntervals() {
   CompoundInterval ci = createCompoundIntervalWithoutRegister();
   assertThat(ci.intersects(new CompoundInterval(null)), is(false));
 }
 @Test
 public void removeIntervalsAndCacheWorksWhenOtherIntervalIsASubset() {
   CompoundInterval ci = createCompoundIntervalWithoutRegister();
   ci.add(new MappedBasicInterval(DEFAULT_END + 1, DEFAULT_END + 2, null));
   ci.add(new MappedBasicInterval(DEFAULT_END + 2, DEFAULT_END + 3, null));
   ci.add(new MappedBasicInterval(DEFAULT_END + 1, DEFAULT_END + 4, null));
   ci.add(new MappedBasicInterval(DEFAULT_BEGIN, DEFAULT_END + 1, null));
   CompoundInterval toRemove = new CompoundInterval(DEFAULT_END + 1, DEFAULT_END + 2, null);
   toRemove.add(new MappedBasicInterval(DEFAULT_BEGIN, DEFAULT_END, null));
   CompoundInterval cached = ci.removeIntervalsAndCache(toRemove);
   assertThat(cached.size(), is(2));
   assertThat(
       cached.contains(new MappedBasicInterval(DEFAULT_BEGIN, DEFAULT_END, null)), is(true));
   assertThat(
       cached.contains(new MappedBasicInterval(DEFAULT_END + 1, DEFAULT_END + 2, null)), is(true));
   assertThat(ci.size(), is(3));
   assertThat(
       ci.contains(new MappedBasicInterval(DEFAULT_BEGIN, DEFAULT_END + 1, null)), is(true));
   assertThat(
       ci.contains(new MappedBasicInterval(DEFAULT_END + 1, DEFAULT_END + 4, null)), is(true));
   assertThat(
       ci.contains(new MappedBasicInterval(DEFAULT_END + 2, DEFAULT_END + 3, null)), is(true));
 }
 @Test
 public void emptyCompoundIntervalsDoNotIntersectWithAnything() {
   CompoundInterval empty = new CompoundInterval(null);
   assertThat(empty.intersects(new CompoundInterval(null)), is(false));
 }