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 }