c.AllocaCStrs; ssa: AllocaU/ArrayAlloca/Times/AllocaCStrs

This commit is contained in:
xushiwei
2024-07-12 21:40:13 +08:00
parent 2d29d1549a
commit e138951e9e
11 changed files with 152 additions and 71 deletions

View File

@@ -144,6 +144,13 @@ func (b Builder) Alloca(n Expr) (ret Expr) {
return
}
// AllocaU allocates uninitialized space for n*sizeof(elem) bytes.
func (b Builder) AllocaU(elem Type, n ...int64) (ret Expr) {
prog := b.Prog
size := SizeOf(prog, elem, n...)
return Expr{b.Alloca(size).impl, prog.Pointer(elem)}
}
// AllocaCStr allocates space for copy it from a Go string.
func (b Builder) AllocaCStr(gostr Expr) (ret Expr) {
if debugInstr {
@@ -155,6 +162,29 @@ func (b Builder) AllocaCStr(gostr Expr) (ret Expr) {
return b.InlineCall(b.Pkg.rtFunc("CStrCopy"), cstr, gostr)
}
// func allocaCStrs(strs []string, endWithNil bool) **int8
func (b Builder) AllocaCStrs(strs Expr, endWithNil bool) (cstrs Expr) {
if debugInstr {
log.Printf("AllocaCStrs %v, %v\n", strs.impl, endWithNil)
}
prog := b.Prog
n := b.SliceLen(strs)
n1 := n
if endWithNil {
n1 = b.BinOp(token.ADD, n, prog.Val(1))
}
tcstr := prog.CStr()
cstrs = b.ArrayAlloca(tcstr, n1)
b.Times(n, func(i Expr) {
s := b.Index(strs, i, nil)
b.Store(b.Advance(cstrs, i), b.AllocaCStr(s))
})
if endWithNil {
b.Store(b.Advance(cstrs, n), prog.Nil(tcstr))
}
return
}
// -----------------------------------------------------------------------------
func (p Program) tyMalloc() *types.Signature {
@@ -189,17 +219,15 @@ func (b Builder) free(ptr Expr) Expr {
// -----------------------------------------------------------------------------
/*
// ArrayAlloca reserves space for an array of n elements of type telem.
func (b Builder) ArrayAlloca(telem Type, n Expr) (ret Expr) {
if debugInstr {
log.Printf("ArrayAlloca %v, %v\n", telem.t, n.impl)
log.Printf("ArrayAlloca %v, %v\n", telem.raw.Type, n.impl)
}
ret.impl = llvm.CreateArrayAlloca(b.impl, telem.ll, n.impl)
ret.Type = b.Prog.Pointer(telem)
return
}
*/
// ArrayAlloc allocates zero initialized space for an array of n elements of type telem.
func (b Builder) ArrayAlloc(telem Type, n Expr) (ret Expr) {

View File

@@ -19,6 +19,7 @@ package ssa
import (
"bytes"
"fmt"
"go/token"
"go/types"
"log"
"strings"
@@ -248,6 +249,44 @@ func (b Builder) IfThen(cond Expr, then func()) {
b.blk.last = blks[1].last
}
/* TODO(xsw):
// For emits a for-loop instruction.
func (b Builder) For(cond func() Expr, loop func()) {
blks := b.Func.MakeBlocks(3)
b.Jump(blks[0])
b.SetBlockEx(blks[0], AtEnd, false)
b.If(cond(), blks[1], blks[2])
b.SetBlockEx(blks[1], AtEnd, false)
loop()
b.Jump(blks[0])
b.SetBlockEx(blks[2], AtEnd, false)
b.blk.last = blks[2].last
}
*/
// Times emits a times-loop instruction.
func (b Builder) Times(n Expr, loop func(i Expr)) {
at := b.blk
blks := b.Func.MakeBlocks(3)
b.Jump(blks[0])
b.SetBlockEx(blks[0], AtEnd, false)
typ := n.Type
phi := b.Phi(typ)
b.If(b.BinOp(token.LSS, phi.Expr, n), blks[1], blks[2])
b.SetBlockEx(blks[1], AtEnd, false)
loop(phi.Expr)
post := b.BinOp(token.ADD, phi.Expr, b.Prog.IntVal(1, typ))
b.Jump(blks[0])
b.SetBlockEx(blks[2], AtEnd, false)
b.blk.last = blks[2].last
phi.AddIncoming(b, []BasicBlock{at, blks[1]}, func(i int, blk BasicBlock) Expr {
if i == 0 {
return b.Prog.IntVal(0, typ)
}
return post
})
}
// -----------------------------------------------------------------------------
/*
type caseStmt struct {