From 0b6a5586679fb0e23bb8f9c5e620ee786e4e3176 Mon Sep 17 00:00:00 2001 From: visualfc Date: Wed, 3 Sep 2025 11:18:20 +0800 Subject: [PATCH] internal/cbi: replaceParamAlloc --- internal/cabi/cabi.go | 50 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/internal/cabi/cabi.go b/internal/cabi/cabi.go index 74e2f397..c72eb6fb 100644 --- a/internal/cabi/cabi.go +++ b/internal/cabi/cabi.go @@ -357,7 +357,20 @@ func (p *Transformer) transformFuncBody(m llvm.Module, ctx llvm.Context, info *F // skip continue case AttrPointer: + // void @fn(%typ %0) + // %1 = alloca %typ, align 8 + // call void @llvm.memset(ptr %1, i8 0, i64 36, i1 false) + // store %typ %0, ptr %1, align 4 + // + // void @fn(ptr byval(%typ) %0) + // %1 = load %typ, ptr %0, align 4 + // %2 = alloca %typ, align 8 + // call void @llvm.memset(ptr %2, i8 0, i64 36, i1 false) + // store %typ %1, ptr %2, align 4 nv = b.CreateLoad(ti.Type, params[index], "") + if p.sys.SupportByVal() { + replaceParamAlloc(fn.Param(i), params[index]) + } case AttrWidthType: iptr := llvm.CreateAlloca(b, ti.Type1) b.CreateStore(params[index], iptr) @@ -654,3 +667,40 @@ func (p *Transformer) getMemcpy(m llvm.Module, ctx llvm.Context) llvm.Value { memcpy.AddFunctionAttr(funcNoUnwind(ctx)) return memcpy } + +func replaceParamAlloc(param llvm.Value, nv llvm.Value) { + u := param.FirstUse() + var storeInstrs []llvm.Value + for !u.IsNil() { + if user := u.User().IsAStoreInst(); !user.IsNil() && user.Operand(0) == param { + storeInstrs = append(storeInstrs, user) + } + u = u.NextUse() + } + for _, instr := range storeInstrs { + if alloc := instr.Operand(1).IsAAllocaInst(); !alloc.IsNil() { + skips := make(map[llvm.Value]bool) + next := llvm.NextInstruction(alloc) + for !next.IsNil() && next != instr { + skips[next] = true + next = llvm.NextInstruction(next) + } + var uses []llvm.Value + u := alloc.FirstUse() + for !u.IsNil() { + if v := u.User(); !skips[v] { + uses = append(uses, v) + } + u = u.NextUse() + } + for _, use := range uses { + n := use.OperandsCount() + for i := 0; i < n; i++ { + if use.Operand(i) == alloc { + use.SetOperand(i, nv) + } + } + } + } + } +}