gorgonia.org/gorgonia@v0.9.17/regalloc_test.go (about)

     1  package gorgonia
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/stretchr/testify/assert"
     7  )
     8  
     9  func TestIntervalMethods(t *testing.T) {
    10  	assert := assert.New(t)
    11  	iv := newInterval()
    12  
    13  	iv.setFrom(2)
    14  
    15  	if !iv.noUsePositions() {
    16  		t.Error("interval has no useposition. How did a usePos get in?")
    17  	}
    18  
    19  	//simulate an register being defined at instruction 2, and its last use was 7
    20  	iv.addRange(2, 8)
    21  	iv.addUsePositions(6)
    22  	assert.Equal([]int{6}, iv.usePositions)
    23  	assert.Equal([]intervalRange{{2, 8}}, iv.ranges)
    24  
    25  	// now comes a new player... it essentially uses the same data in the same register as iv
    26  	// but was defined a few instructions down the road.
    27  	iv2 := newInterval()
    28  	iv2.addRange(20, 25)
    29  	iv2.addUsePositions(22)
    30  
    31  	iv.merge(iv2)
    32  	assert.Equal([]int{6, 22}, iv.usePositions)
    33  	assert.Equal(iv2.end, iv.end)
    34  	assert.Equal(2, iv.start)
    35  	assert.Equal([]intervalRange{iv.ranges[0], iv2.ranges[0]}, iv.ranges)
    36  }
    37  
    38  func TestRegAlloc(t *testing.T) {
    39  	var sorted Nodes
    40  	var err error
    41  
    42  	g, x, y, z := simpleVecEqn()
    43  	z2 := Must(Square(z))
    44  	if sorted, err = Sort(g); err != nil {
    45  		t.Fatal(err)
    46  	}
    47  	reverseNodes(sorted)
    48  
    49  	df := analyze(g, sorted)
    50  	df.buildIntervals(sorted)
    51  	is := df.intervals
    52  
    53  	ra := newRegalloc(df)
    54  	ra.alloc(sorted)
    55  
    56  	if is[x].result.id >= len(is) {
    57  		t.Error("x is an input, and would have a lifetime of the entire program")
    58  	}
    59  
    60  	if is[y].result.id >= len(is) {
    61  		t.Error("y is an input, and would have a lifetime of the entire program")
    62  	}
    63  
    64  	var onDev bool
    65  	switch z2.op.(type) {
    66  	case CUDADoer:
    67  		onDev = true
    68  	case CLDoer:
    69  		onDev = true
    70  	}
    71  
    72  	switch {
    73  	case z2.op.CallsExtern() && !onDev:
    74  		if is[z].result.id == is[z2].result.id {
    75  			t.Error("z2 should NOT reuse the register of z")
    76  		}
    77  	default:
    78  		if is[z].result.id != is[z2].result.id {
    79  			t.Error("z2 should reuse the register of z")
    80  		}
    81  	}
    82  
    83  }