c.AllocaCStrs; ssa: AllocaU/ArrayAlloca/Times/AllocaCStrs
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user