tinygo/transform/allocs_test.go
Ayke van Laethem 3b1913ac57 all: use the new LLVM pass manager
The old LLVM pass manager is deprecated and should not be used anymore.
Moreover, the pass manager builder (which we used to set up a pass
pipeline) is actually removed from LLVM entirely in LLVM 17:
https://reviews.llvm.org/D145387
https://reviews.llvm.org/D145835

The new pass manager does change the binary size in many cases: both
growing and shrinking it. However, on average the binary size remains
more or less the same.

This is needed as a preparation for LLVM 17.
2023-10-04 13:05:58 +02:00

81 строка
2 КиБ
Go

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, 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("."), 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)
}
}