llgo/ssa: StringData/StringLen

This commit is contained in:
xushiwei
2024-05-12 15:42:50 +08:00
parent acecbf587d
commit 090149eab6
22 changed files with 71 additions and 72 deletions

View File

@@ -598,6 +598,26 @@ func (b Builder) getField(x Expr, idx int) Expr {
return Expr{fld, tfld}
}
// StringData returns the data pointer of a string.
func (b Builder) StringData(x Expr) Expr {
if debugInstr {
log.Printf("StringData %v\n", x.impl)
}
prog := b.Prog
ptr := llvm.CreateExtractValue(b.impl, x.impl, 0)
return Expr{ptr, prog.CStr()}
}
// StringLen returns the length of a string.
func (b Builder) StringLen(x Expr) Expr {
if debugInstr {
log.Printf("StringLen %v\n", x.impl)
}
prog := b.Prog
ptr := llvm.CreateExtractValue(b.impl, x.impl, 1)
return Expr{ptr, prog.Int()}
}
// The IndexAddr instruction yields the address of the element at
// index `idx` of collection `x`. `idx` is an integer expression.
//
@@ -649,8 +669,7 @@ func (b Builder) Index(x, idx Expr, addr func(Expr) Expr) Expr {
panic(fmt.Errorf("invalid operation: cannot index %v", t))
}
telem = prog.rawType(types.Typ[types.Byte])
pkg := b.Func.Pkg
ptr = b.InlineCall(pkg.rtFunc("StringData"), x)
ptr = b.StringData(x)
case *types.Array:
telem = prog.Index(x.Type)
if addr != nil {
@@ -717,7 +736,7 @@ func (b Builder) Slice(x, low, high, max Expr) (ret Expr) {
panic(fmt.Errorf("invalid operation: cannot slice %v", t))
}
if high.IsNil() {
high = b.InlineCall(pkg.rtFunc("StringLen"), x)
high = b.StringLen(x)
}
ret.Type = x.Type
ret.impl = b.InlineCall(pkg.rtFunc("NewStringSlice"), x, low, high).impl
@@ -871,7 +890,7 @@ func (b Builder) AllocaCStr(gostr Expr) (ret Expr) {
log.Printf("AllocaCStr %v\n", gostr.impl)
}
pkg := b.Func.Pkg
n := b.InlineCall(pkg.rtFunc("StringLen"), gostr)
n := b.StringLen(gostr)
n1 := b.BinOp(token.ADD, n, b.Prog.Val(1))
cstr := b.Alloca(n1)
return b.InlineCall(pkg.rtFunc("CStrCopy"), cstr, gostr)
@@ -1250,7 +1269,7 @@ func (b Builder) BuiltinCall(fn string, args ...Expr) (ret Expr) {
return b.InlineCall(b.Func.Pkg.rtFunc("SliceLen"), arg)
case *types.Basic:
if t.Kind() == types.String {
return b.InlineCall(b.Func.Pkg.rtFunc("StringLen"), arg)
return b.StringLen(arg)
}
}
}