1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
package transform_test
import (
"go/token"
"os"
"path/filepath"
"regexp"
"sort"
"strconv"
"strings"
"testing"
"github.com/tinygo-org/tinygo/transform"
"tinygo.org/x/go-llvm"
)
func TestAllocs(t *testing.T) {
t.Parallel()
testTransform(t, "testdata/allocs", func(mod llvm.Module) {
transform.OptimizeAllocs(mod, nil, 256, nil)
})
}
type allocsTestOutput struct {
filename string
line int
msg string
}
func (out allocsTestOutput) String() string {
return out.filename + ":" + strconv.Itoa(out.line) + ": " + out.msg
}
// Test with a Go file as input (for more accurate tests).
func TestAllocs2(t *testing.T) {
t.Parallel()
mod := compileGoFileForTesting(t, "./testdata/allocs2.go")
// Run functionattrs pass, which is necessary for escape analysis.
po := llvm.NewPassBuilderOptions()
defer po.Dispose()
err := mod.RunPasses("function(instcombine),function-attrs", llvm.TargetMachine{}, po)
if err != nil {
t.Error("failed to run passes:", err)
}
// Run heap to stack transform.
var testOutputs []allocsTestOutput
transform.OptimizeAllocs(mod, regexp.MustCompile("."), 256, func(pos token.Position, msg string) {
testOutputs = append(testOutputs, allocsTestOutput{
filename: filepath.Base(pos.Filename),
line: pos.Line,
msg: msg,
})
})
sort.Slice(testOutputs, func(i, j int) bool {
return testOutputs[i].line < testOutputs[j].line
})
testOutput := ""
for _, out := range testOutputs {
testOutput += out.String() + "\n"
}
// Load expected test output (the OUT: lines).
testInput, err := os.ReadFile("./testdata/allocs2.go")
if err != nil {
t.Fatal("could not read test input:", err)
}
var expectedTestOutput string
for i, line := range strings.Split(strings.ReplaceAll(string(testInput), "\r\n", "\n"), "\n") {
if idx := strings.Index(line, " // OUT: "); idx > 0 {
msg := line[idx+len(" // OUT: "):]
expectedTestOutput += "allocs2.go:" + strconv.Itoa(i+1) + ": " + msg + "\n"
}
}
if testOutput != expectedTestOutput {
t.Errorf("output does not match expected output:\n%s", testOutput)
}
}
|