aboutsummaryrefslogtreecommitdiffhomepage
path: root/transform
diff options
context:
space:
mode:
authorDamian Gryski <[email protected]>2023-10-19 23:00:54 -0700
committerRon Evans <[email protected]>2024-01-31 17:51:55 +0100
commit2867da164dc6352ce1165d5a9e87103a4d8b74aa (patch)
tree52bb6639d31e7965ae0c0cb6c91b24f27288cc4d /transform
parent7b8ae2d6b62bf2bc76b8529147d24137df6ff8ec (diff)
downloadtinygo-2867da164dc6352ce1165d5a9e87103a4d8b74aa.tar.gz
tinygo-2867da164dc6352ce1165d5a9e87103a4d8b74aa.zip
Allow larger systems to have a larger max stack alloc
Fixes #3331
Diffstat (limited to 'transform')
-rw-r--r--transform/allocs.go10
-rw-r--r--transform/allocs_test.go4
-rw-r--r--transform/optimizer.go5
3 files changed, 6 insertions, 13 deletions
diff --git a/transform/allocs.go b/transform/allocs.go
index 908d72e7b..67ca1ea43 100644
--- a/transform/allocs.go
+++ b/transform/allocs.go
@@ -13,14 +13,6 @@ import (
"tinygo.org/x/go-llvm"
)
-// maxStackAlloc is the maximum size of an object that will be allocated on the
-// stack. Bigger objects have increased risk of stack overflows and thus will
-// always be heap allocated.
-//
-// TODO: tune this, this is just a random value.
-// This value is also used in the compiler when translating ssa.Alloc nodes.
-const maxStackAlloc = 256
-
// OptimizeAllocs tries to replace heap allocations with stack allocations
// whenever possible. It relies on the LLVM 'nocapture' flag for interprocedural
// escape analysis, and within a function looks whether an allocation can escape
@@ -28,7 +20,7 @@ const maxStackAlloc = 256
// If printAllocs is non-nil, it indicates the regexp of functions for which a
// heap allocation explanation should be printed (why the object can't be stack
// allocated).
-func OptimizeAllocs(mod llvm.Module, printAllocs *regexp.Regexp, logger func(token.Position, string)) {
+func OptimizeAllocs(mod llvm.Module, printAllocs *regexp.Regexp, maxStackAlloc uint64, logger func(token.Position, string)) {
allocator := mod.NamedFunction("runtime.alloc")
if allocator.IsNil() {
// nothing to optimize
diff --git a/transform/allocs_test.go b/transform/allocs_test.go
index 59a5b14e2..7f7ff5b75 100644
--- a/transform/allocs_test.go
+++ b/transform/allocs_test.go
@@ -17,7 +17,7 @@ import (
func TestAllocs(t *testing.T) {
t.Parallel()
testTransform(t, "testdata/allocs", func(mod llvm.Module) {
- transform.OptimizeAllocs(mod, nil, nil)
+ transform.OptimizeAllocs(mod, nil, 256, nil)
})
}
@@ -47,7 +47,7 @@ func TestAllocs2(t *testing.T) {
// Run heap to stack transform.
var testOutputs []allocsTestOutput
- transform.OptimizeAllocs(mod, regexp.MustCompile("."), func(pos token.Position, msg string) {
+ transform.OptimizeAllocs(mod, regexp.MustCompile("."), 256, func(pos token.Position, msg string) {
testOutputs = append(testOutputs, allocsTestOutput{
filename: filepath.Base(pos.Filename),
line: pos.Line,
diff --git a/transform/optimizer.go b/transform/optimizer.go
index 42acc2ddc..e73e97600 100644
--- a/transform/optimizer.go
+++ b/transform/optimizer.go
@@ -64,7 +64,8 @@ func Optimize(mod llvm.Module, config *compileopts.Config) []error {
// Run TinyGo-specific optimization passes.
OptimizeStringToBytes(mod)
OptimizeReflectImplements(mod)
- OptimizeAllocs(mod, nil, nil)
+ maxStackSize := config.MaxStackAlloc()
+ OptimizeAllocs(mod, nil, maxStackSize, nil)
err = LowerInterfaces(mod, config)
if err != nil {
return []error{err}
@@ -84,7 +85,7 @@ func Optimize(mod llvm.Module, config *compileopts.Config) []error {
}
// Run TinyGo-specific interprocedural optimizations.
- OptimizeAllocs(mod, config.Options.PrintAllocs, func(pos token.Position, msg string) {
+ OptimizeAllocs(mod, config.Options.PrintAllocs, maxStackSize, func(pos token.Position, msg string) {
fmt.Fprintln(os.Stderr, pos.String()+": "+msg)
})
OptimizeStringToBytes(mod)