From 7ffbcbc6669ee4e8a175df74f53d0d3aa273ff43 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Mon, 25 May 2026 18:09:01 +0200 Subject: [PATCH] compiler: refactor runtime.alloc call This refactor makes no other changes. --- compiler/compiler.go | 15 ++------------- compiler/defer.go | 2 +- compiler/gc.go | 19 +++++++++++++++++++ compiler/llvm.go | 6 +----- 4 files changed, 23 insertions(+), 19 deletions(-) diff --git a/compiler/compiler.go b/compiler/compiler.go index 7c7f7c0b0..2b3419ed4 100644 --- a/compiler/compiler.go +++ b/compiler/compiler.go @@ -196,16 +196,6 @@ func newBuilder(c *compilerContext, irbuilder llvm.Builder, f *ssa.Function) *bu } } -// Return the runtime.alloc function variant. -// This is normally just "alloc", but is "alloc_noheap" if the //go:noheap -// pragma is used. -func (b *builder) allocFunc() string { - if b.info.noheap { - return "alloc_noheap" - } - return "alloc" -} - type blockInfo struct { // entry is the LLVM basic block corresponding to the start of this *ssa.Block. entry llvm.BasicBlock @@ -2197,9 +2187,8 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) { } sizeValue := llvm.ConstInt(b.uintptrType, size, false) layoutValue := b.createObjectLayout(typ, expr.Pos()) - buf := b.createRuntimeCall(b.allocFunc(), []llvm.Value{sizeValue, layoutValue}, expr.Comment) align := b.targetData.ABITypeAlignment(typ) - buf.AddCallSiteAttribute(0, b.ctx.CreateEnumAttribute(llvm.AttributeKindID("align"), uint64(align))) + buf := b.createAlloc(sizeValue, layoutValue, align, expr.Comment) return buf, nil } else { buf := llvmutil.CreateEntryBlockAlloca(b.Builder, typ, expr.Comment) @@ -2429,7 +2418,7 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) { } sliceSize := b.CreateBinOp(llvm.Mul, elemSizeValue, sliceCapCast, "makeslice.cap") layoutValue := b.createObjectLayout(llvmElemType, expr.Pos()) - slicePtr := b.createRuntimeCall(b.allocFunc(), []llvm.Value{sliceSize, layoutValue}, "makeslice.buf") + slicePtr := b.createAlloc(sliceSize, layoutValue, 0, "makeslice.buf") slicePtr.AddCallSiteAttribute(0, b.ctx.CreateEnumAttribute(llvm.AttributeKindID("align"), uint64(elemAlign))) // Extend or truncate if necessary. This is safe as we've already done diff --git a/compiler/defer.go b/compiler/defer.go index b0bc3a967..666b3f465 100644 --- a/compiler/defer.go +++ b/compiler/defer.go @@ -505,7 +505,7 @@ func (b *builder) createDefer(instr *ssa.Defer) { size := b.targetData.TypeAllocSize(deferredCallType) sizeValue := llvm.ConstInt(b.uintptrType, size, false) nilPtr := llvm.ConstNull(b.dataPtrType) - alloca = b.createRuntimeCall(b.allocFunc(), []llvm.Value{sizeValue, nilPtr}, "defer.alloc.call") + alloca = b.createAlloc(sizeValue, nilPtr, 0, "defer.alloc.call") } if b.NeedsStackObjects { b.trackPointer(alloca) diff --git a/compiler/gc.go b/compiler/gc.go index 5ca79b91b..5c59373a9 100644 --- a/compiler/gc.go +++ b/compiler/gc.go @@ -10,6 +10,25 @@ import ( "tinygo.org/x/go-llvm" ) +// Heap-allocate a buffer of the given size. This will typically call +// runtime.alloc. +func (b *builder) createAlloc(sizeValue, layoutValue llvm.Value, align int, comment string) llvm.Value { + // Normally allocate using "runtime.alloc", but use "runtime.alloc_noheap" + // if the //go:noheap pragma is used. + allocFunc := "alloc" + if b.info.noheap { + allocFunc = "alloc_noheap" + } + + call := b.createRuntimeCall(allocFunc, []llvm.Value{sizeValue, layoutValue}, comment) + if align != 0 { + // TODO: make sure all callsites set the correct alignment. + call.AddCallSiteAttribute(0, b.ctx.CreateEnumAttribute(llvm.AttributeKindID("align"), uint64(align))) + } + + return call +} + // trackExpr inserts pointer tracking intrinsics for the GC if the expression is // one of the expressions that need this. func (b *builder) trackExpr(expr ssa.Value, value llvm.Value) { diff --git a/compiler/llvm.go b/compiler/llvm.go index c25a8d4a3..a7fe725bb 100644 --- a/compiler/llvm.go +++ b/compiler/llvm.go @@ -129,11 +129,7 @@ func (b *builder) emitPointerPack(values []llvm.Value) llvm.Value { // Packed data is bigger than a pointer, so allocate it on the heap. sizeValue := llvm.ConstInt(b.uintptrType, size, false) align := b.targetData.ABITypeAlignment(packedType) - packedAlloc := b.createRuntimeCall(b.allocFunc(), []llvm.Value{ - sizeValue, - llvm.ConstNull(b.dataPtrType), - }, "") - packedAlloc.AddCallSiteAttribute(0, b.ctx.CreateEnumAttribute(llvm.AttributeKindID("align"), uint64(align))) + packedAlloc := b.createAlloc(sizeValue, llvm.ConstNull(b.dataPtrType), align, "") if b.NeedsStackObjects { b.trackPointer(packedAlloc) }