diff --git a/internal/runtime/z_rt.go b/internal/runtime/z_rt.go index d6f54486..672adf62 100644 --- a/internal/runtime/z_rt.go +++ b/internal/runtime/z_rt.go @@ -95,11 +95,6 @@ func stringTracef(fp c.FilePtr, format *c.Char, s String) { // ----------------------------------------------------------------------------- -// Zeroinit initializes memory to zero. -func Zeroinit(p unsafe.Pointer, size uintptr) unsafe.Pointer { - return c.Memset(p, 0, size) -} - // New allocates memory and initializes it to zero. func New(t *Type) unsafe.Pointer { return AllocZ(t.Size_) diff --git a/ssa/memory.go b/ssa/memory.go index d14fd71b..d9f469e9 100644 --- a/ssa/memory.go +++ b/ssa/memory.go @@ -110,7 +110,7 @@ func (b Builder) Alloc(elem Type, heap bool) (ret Expr) { ret = b.InlineCall(pkg.rtFunc("AllocZ"), size) } else { ret = Expr{llvm.CreateAlloca(b.impl, elem.ll), prog.VoidPtr()} - ret.impl = b.InlineCall(pkg.rtFunc("Zeroinit"), ret, size).impl + ret.impl = b.zeroinit(ret, size).impl } ret.Type = prog.Pointer(elem) return @@ -210,6 +210,18 @@ func (p Program) tyFree() *types.Signature { return p.freeTy } +func (p Program) tyMemsetInline() *types.Signature { + if p.memsetInlineTy == nil { + paramPtr := types.NewParam(token.NoPos, nil, "", p.VoidPtr().raw.Type) + paramInt := types.NewParam(token.NoPos, nil, "", p.Byte().raw.Type) + paramSize := types.NewParam(token.NoPos, nil, "", p.Uintptr().raw.Type) + paramBool := types.NewParam(token.NoPos, nil, "", p.Bool().raw.Type) + params := types.NewTuple(paramPtr, paramInt, paramSize, paramBool) + p.memsetInlineTy = types.NewSignatureType(nil, nil, nil, params, nil, false) + } + return p.memsetInlineTy +} + func (b Builder) malloc(size Expr) Expr { fn := b.Pkg.cFunc("malloc", b.Prog.tyMalloc()) return b.Call(fn, size) @@ -220,6 +232,18 @@ func (b Builder) free(ptr Expr) Expr { return b.Call(fn, ptr) } +// declare void @llvm.memset.inline.p0.p0i8.i32(ptr , i8 , i32 , i1 ) +// declare void @llvm.memset.inline.p0.p0.i64(ptr , i8 , i64 , i1 ) +func (b Builder) memset(ptr, val, len, isvolatile Expr) Expr { + fn := b.Pkg.cFunc("llvm.memset", b.Prog.tyMemsetInline()) + b.Call(fn, ptr, val, len, isvolatile) + return ptr +} + +func (b Builder) zeroinit(ptr, size Expr) Expr { + return b.memset(ptr, b.Prog.IntVal(0, b.Prog.Byte()), size, b.Prog.Val(false)) +} + // ----------------------------------------------------------------------------- // ArrayAlloca reserves space for an array of n elements of type telem. diff --git a/ssa/package.go b/ssa/package.go index 020cbda6..4554b56d 100644 --- a/ssa/package.go +++ b/ssa/package.go @@ -179,8 +179,9 @@ type aProgram struct { getAttrStr *types.Signature pyUniStr *types.Signature - mallocTy *types.Signature - freeTy *types.Signature + mallocTy *types.Signature + freeTy *types.Signature + memsetInlineTy *types.Signature createKeyTy *types.Signature getSpecTy *types.Signature