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
|
||||
printspaceFunc llvm.Value
|
||||
printnlFunc llvm.Value
|
||||
memsetIntrinsic llvm.Value
|
||||
itfTypeNumbers map[types.Type]uint64
|
||||
itfTypes []types.Type
|
||||
initFuncs []llvm.Value
|
||||
|
@ -132,16 +131,6 @@ func NewCompiler(pkgName, triple string) (*Compiler, error) {
|
|||
printnlType := llvm.FunctionType(llvm.VoidType(), nil, false)
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
if _, ok := c.itfTypeNumbers[typ]; !ok {
|
||||
num := uint64(len(c.itfTypes))
|
||||
|
@ -686,20 +708,14 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) {
|
|||
} else {
|
||||
buf = c.builder.CreateAlloca(typ, expr.Comment)
|
||||
}
|
||||
width := c.targetData.TypeAllocSize(typ)
|
||||
if err != nil {
|
||||
return llvm.Value{}, err
|
||||
}
|
||||
llvmWidth := llvm.ConstInt(llvm.Int32Type(), width, false)
|
||||
bufBytes := c.builder.CreateBitCast(buf, llvm.PointerType(llvm.Int8Type(), 0), "")
|
||||
c.builder.CreateCall(
|
||||
c.memsetIntrinsic,
|
||||
[]llvm.Value{
|
||||
bufBytes,
|
||||
llvm.ConstInt(llvm.Int8Type(), 0, false), // value to set (zero)
|
||||
llvmWidth, // size to zero
|
||||
llvm.ConstInt(llvm.Int1Type(), 0, false), // volatile
|
||||
}, "")
|
||||
zero, err := c.getZeroValue(typ)
|
||||
if err != nil {
|
||||
return llvm.Value{}, err
|
||||
}
|
||||
c.builder.CreateStore(zero, buf) // zero-initialize var
|
||||
return buf, nil
|
||||
case *ssa.BinOp:
|
||||
return c.parseBinOp(frame, expr)
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче