diff options
author | Jaden Weiss <[email protected]> | 2019-11-13 10:05:01 -0500 |
---|---|---|
committer | Ayke <[email protected]> | 2019-11-13 16:45:09 +0100 |
commit | 93961f9d411d28c7acae5f556ffdabc4b3b6871e (patch) | |
tree | 49dfc743a91463b32b7c38dc2ac8efb38e3dca9b /transform | |
parent | acdaaa17d8232989d310292a512e70fccdb288a5 (diff) | |
download | tinygo-93961f9d411d28c7acae5f556ffdabc4b3b6871e.tar.gz tinygo-93961f9d411d28c7acae5f556ffdabc4b3b6871e.zip |
fix incorrect starting value for optimized allocations in a loop
Diffstat (limited to 'transform')
-rw-r--r-- | transform/allocs.go | 5 | ||||
-rw-r--r-- | transform/testdata/allocs.ll | 14 | ||||
-rw-r--r-- | transform/testdata/allocs.out.ll | 14 | ||||
-rw-r--r-- | transform/transform_test.go | 5 |
4 files changed, 36 insertions, 2 deletions
diff --git a/transform/allocs.go b/transform/allocs.go index 4f006c3a9..f21dde123 100644 --- a/transform/allocs.go +++ b/transform/allocs.go @@ -69,8 +69,13 @@ func OptimizeAllocs(mod llvm.Module) { sizeInWords := (size + uint64(alignment) - 1) / uint64(alignment) allocaType := llvm.ArrayType(mod.Context().IntType(alignment*8), int(sizeInWords)) alloca := builder.CreateAlloca(allocaType, "stackalloc.alloca") + + // Zero the allocation inside the block where the value was originally allocated. zero := llvm.ConstNull(alloca.Type().ElementType()) + builder.SetInsertPointBefore(bitcast) builder.CreateStore(zero, alloca) + + // Replace heap alloc bitcast with stack alloc bitcast. stackalloc := builder.CreateBitCast(alloca, bitcast.Type(), "stackalloc") bitcast.ReplaceAllUsesWith(stackalloc) if heapalloc != bitcast { diff --git a/transform/testdata/allocs.ll b/transform/testdata/allocs.ll index 87718aee5..0511d79df 100644 --- a/transform/testdata/allocs.ll +++ b/transform/testdata/allocs.ll @@ -54,6 +54,20 @@ define i32* @testEscapingReturn() { ret i32* %2 } +; Do a non-escaping allocation in a loop. +define void @testNonEscapingLoop() { +entry: + br label %loop +loop: + %0 = call i8* @runtime.alloc(i32 4) + %1 = bitcast i8* %0 to i32* + %2 = call i32* @noescapeIntPtr(i32* %1) + %3 = icmp eq i32* null, %2 + br i1 %3, label %loop, label %end +end: + ret void +} + declare i32* @escapeIntPtr(i32*) declare i32* @noescapeIntPtr(i32* nocapture) diff --git a/transform/testdata/allocs.out.ll b/transform/testdata/allocs.out.ll index eb92d6ed3..e788beeba 100644 --- a/transform/testdata/allocs.out.ll +++ b/transform/testdata/allocs.out.ll @@ -50,6 +50,20 @@ define i32* @testEscapingReturn() { ret i32* %2 } +define void @testNonEscapingLoop() { +entry: + %stackalloc.alloca = alloca [1 x i32] + br label %loop +loop: + store [1 x i32] zeroinitializer, [1 x i32]* %stackalloc.alloca + %stackalloc = bitcast [1 x i32]* %stackalloc.alloca to i32* + %0 = call i32* @noescapeIntPtr(i32* %stackalloc) + %1 = icmp eq i32* null, %0 + br i1 %1, label %loop, label %end +end: + ret void +} + declare i32* @escapeIntPtr(i32*) declare i32* @noescapeIntPtr(i32* nocapture) diff --git a/transform/transform_test.go b/transform/transform_test.go index 12240ac5b..d0f125692 100644 --- a/transform/transform_test.go +++ b/transform/transform_test.go @@ -70,8 +70,9 @@ func fuzzyEqualIR(s1, s2 string) bool { func filterIrrelevantIRLines(lines []string) []string { var out []string for _, line := range lines { - line = strings.TrimSpace(line) // drop '\r' on Windows - if line == "" || line[0] == ';' { + line = strings.Split(line, ";")[0] // strip out comments/info + line = strings.TrimRight(line, "\r ") // drop '\r' on Windows and remove trailing spaces from comments + if line == "" { continue } if strings.HasPrefix(line, "source_filename = ") { |