compiler: Use zeroinitializer instead of memset
Этот коммит содержится в:
родитель
6ed1ca11c7
коммит
14cbc1555d
1 изменённых файлов: 38 добавлений и 22 удалений
60
tgo.go
60
tgo.go
|
@ -54,7 +54,6 @@ type Compiler struct {
|
||||||
printbyteFunc llvm.Value
|
printbyteFunc llvm.Value
|
||||||
printspaceFunc llvm.Value
|
printspaceFunc llvm.Value
|
||||||
printnlFunc llvm.Value
|
printnlFunc llvm.Value
|
||||||
memsetIntrinsic llvm.Value
|
|
||||||
itfTypeNumbers map[types.Type]uint64
|
itfTypeNumbers map[types.Type]uint64
|
||||||
itfTypes []types.Type
|
itfTypes []types.Type
|
||||||
initFuncs []llvm.Value
|
initFuncs []llvm.Value
|
||||||
|
@ -132,16 +131,6 @@ func NewCompiler(pkgName, triple string) (*Compiler, error) {
|
||||||
printnlType := llvm.FunctionType(llvm.VoidType(), nil, false)
|
printnlType := llvm.FunctionType(llvm.VoidType(), nil, false)
|
||||||
c.printnlFunc = llvm.AddFunction(c.mod, "runtime.printnl", printnlType)
|
c.printnlFunc = llvm.AddFunction(c.mod, "runtime.printnl", printnlType)
|
||||||
|
|
||||||
// Intrinsic functions
|
|
||||||
memsetType := llvm.FunctionType(
|
|
||||||
llvm.VoidType(), []llvm.Type{
|
|
||||||
llvm.PointerType(llvm.Int8Type(), 0),
|
|
||||||
llvm.Int8Type(),
|
|
||||||
llvm.Int32Type(),
|
|
||||||
llvm.Int1Type(),
|
|
||||||
}, false)
|
|
||||||
c.memsetIntrinsic = llvm.AddFunction(c.mod, "llvm.memset.p0i8.i32", memsetType)
|
|
||||||
|
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,6 +281,39 @@ func (c *Compiler) getLLVMType(goType types.Type) (llvm.Type, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Compiler) getZeroValue(typ llvm.Type) (llvm.Value, error) {
|
||||||
|
switch typ.TypeKind() {
|
||||||
|
case llvm.ArrayTypeKind:
|
||||||
|
subTyp := typ.ElementType()
|
||||||
|
vals := make([]llvm.Value, typ.ArrayLength())
|
||||||
|
for i := range vals {
|
||||||
|
val, err := c.getZeroValue(subTyp)
|
||||||
|
if err != nil {
|
||||||
|
return llvm.Value{}, err
|
||||||
|
}
|
||||||
|
vals[i] = val
|
||||||
|
}
|
||||||
|
return llvm.ConstArray(subTyp, vals), nil
|
||||||
|
case llvm.IntegerTypeKind:
|
||||||
|
return llvm.ConstInt(typ, 0, false), nil
|
||||||
|
case llvm.PointerTypeKind:
|
||||||
|
return llvm.ConstPointerNull(typ), nil
|
||||||
|
case llvm.StructTypeKind:
|
||||||
|
types := typ.StructElementTypes()
|
||||||
|
vals := make([]llvm.Value, len(types))
|
||||||
|
for i, subTyp := range types {
|
||||||
|
val, err := c.getZeroValue(subTyp)
|
||||||
|
if err != nil {
|
||||||
|
return llvm.Value{}, err
|
||||||
|
}
|
||||||
|
vals[i] = val
|
||||||
|
}
|
||||||
|
return llvm.ConstStruct(vals, false), nil
|
||||||
|
default:
|
||||||
|
return llvm.Value{}, errors.New("todo: LLVM zero initializer")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Compiler) getInterfaceType(typ types.Type) llvm.Value {
|
func (c *Compiler) getInterfaceType(typ types.Type) llvm.Value {
|
||||||
if _, ok := c.itfTypeNumbers[typ]; !ok {
|
if _, ok := c.itfTypeNumbers[typ]; !ok {
|
||||||
num := uint64(len(c.itfTypes))
|
num := uint64(len(c.itfTypes))
|
||||||
|
@ -686,20 +708,14 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) {
|
||||||
} else {
|
} else {
|
||||||
buf = c.builder.CreateAlloca(typ, expr.Comment)
|
buf = c.builder.CreateAlloca(typ, expr.Comment)
|
||||||
}
|
}
|
||||||
width := c.targetData.TypeAllocSize(typ)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return llvm.Value{}, err
|
return llvm.Value{}, err
|
||||||
}
|
}
|
||||||
llvmWidth := llvm.ConstInt(llvm.Int32Type(), width, false)
|
zero, err := c.getZeroValue(typ)
|
||||||
bufBytes := c.builder.CreateBitCast(buf, llvm.PointerType(llvm.Int8Type(), 0), "")
|
if err != nil {
|
||||||
c.builder.CreateCall(
|
return llvm.Value{}, err
|
||||||
c.memsetIntrinsic,
|
}
|
||||||
[]llvm.Value{
|
c.builder.CreateStore(zero, buf) // zero-initialize var
|
||||||
bufBytes,
|
|
||||||
llvm.ConstInt(llvm.Int8Type(), 0, false), // value to set (zero)
|
|
||||||
llvmWidth, // size to zero
|
|
||||||
llvm.ConstInt(llvm.Int1Type(), 0, false), // volatile
|
|
||||||
}, "")
|
|
||||||
return buf, nil
|
return buf, nil
|
||||||
case *ssa.BinOp:
|
case *ssa.BinOp:
|
||||||
return c.parseBinOp(frame, expr)
|
return c.parseBinOp(frame, expr)
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче