@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)); }