all: remove pointer ElementType calls
This is needed for opaque pointers, which are enabled by default in LLVM 15.
Этот коммит содержится в:
родитель
229746b71e
коммит
62df1d7490
17 изменённых файлов: 82 добавлений и 93 удалений
|
@ -411,7 +411,7 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
|
|||
return errors.New("global not found: " + globalName)
|
||||
}
|
||||
name := global.Name()
|
||||
newGlobal := llvm.AddGlobal(mod, global.Type().ElementType(), name+".tmp")
|
||||
newGlobal := llvm.AddGlobal(mod, global.GlobalValueType(), name+".tmp")
|
||||
global.ReplaceAllUsesWith(newGlobal)
|
||||
global.EraseFromParentAsGlobal()
|
||||
newGlobal.SetName(name)
|
||||
|
@ -1127,7 +1127,7 @@ func setGlobalValues(mod llvm.Module, globals map[string]map[string]string) erro
|
|||
|
||||
// A strin is a {ptr, len} pair. We need these types to build the
|
||||
// initializer.
|
||||
initializerType := global.Type().ElementType()
|
||||
initializerType := global.GlobalValueType()
|
||||
if initializerType.TypeKind() != llvm.StructTypeKind || initializerType.StructName() == "" {
|
||||
return fmt.Errorf("%s: not a string", globalName)
|
||||
}
|
||||
|
|
|
@ -91,7 +91,7 @@ func (b *builder) createSliceToArrayPointerCheck(sliceLen llvm.Value, arrayLen i
|
|||
|
||||
// createUnsafeSliceCheck inserts a runtime check used for unsafe.Slice. This
|
||||
// function must panic if the ptr/len parameters are invalid.
|
||||
func (b *builder) createUnsafeSliceCheck(ptr, len llvm.Value, lenType *types.Basic) {
|
||||
func (b *builder) createUnsafeSliceCheck(ptr, len llvm.Value, elementType llvm.Type, lenType *types.Basic) {
|
||||
// From the documentation of unsafe.Slice:
|
||||
// > At run time, if len is negative, or if ptr is nil and len is not
|
||||
// > zero, a run-time panic occurs.
|
||||
|
@ -105,7 +105,7 @@ func (b *builder) createUnsafeSliceCheck(ptr, len llvm.Value, lenType *types.Bas
|
|||
|
||||
// Determine the maximum slice size, and therefore the maximum value of the
|
||||
// len parameter.
|
||||
maxSize := b.maxSliceSize(ptr.Type().ElementType())
|
||||
maxSize := b.maxSliceSize(elementType)
|
||||
maxSizeValue := llvm.ConstInt(len.Type(), maxSize, false)
|
||||
|
||||
// Do the check. By using unsigned greater than for the length check, signed
|
||||
|
|
|
@ -20,7 +20,7 @@ const maxFieldsPerParam = 3
|
|||
type paramInfo struct {
|
||||
llvmType llvm.Type
|
||||
name string // name, possibly with suffixes for e.g. struct fields
|
||||
flags paramFlags
|
||||
elemSize uint64 // size of pointer element type, or 0 if this isn't a pointer
|
||||
}
|
||||
|
||||
// paramFlags identifies parameter attributes for flags. Most importantly, it
|
||||
|
@ -96,13 +96,7 @@ func (c *compilerContext) expandFormalParamType(t llvm.Type, name string, goType
|
|||
// failed to expand this parameter: too many fields
|
||||
}
|
||||
// TODO: split small arrays
|
||||
return []paramInfo{
|
||||
{
|
||||
llvmType: t,
|
||||
name: name,
|
||||
flags: getTypeFlags(goType),
|
||||
},
|
||||
}
|
||||
return []paramInfo{c.getParamInfo(t, name, goType)}
|
||||
}
|
||||
|
||||
// expandFormalParamOffsets returns a list of offsets from the start of an
|
||||
|
@ -152,7 +146,6 @@ func (b *builder) expandFormalParam(v llvm.Value) []llvm.Value {
|
|||
// Try to flatten a struct type to a list of types. Returns a 1-element slice
|
||||
// with the passed in type if this is not possible.
|
||||
func (c *compilerContext) flattenAggregateType(t llvm.Type, name string, goType types.Type) []paramInfo {
|
||||
typeFlags := getTypeFlags(goType)
|
||||
switch t.TypeKind() {
|
||||
case llvm.StructTypeKind:
|
||||
var paramInfos []paramInfo
|
||||
|
@ -183,40 +176,37 @@ func (c *compilerContext) flattenAggregateType(t llvm.Type, name string, goType
|
|||
}
|
||||
}
|
||||
subInfos := c.flattenAggregateType(subfield, name+"."+suffix, extractSubfield(goType, i))
|
||||
for i := range subInfos {
|
||||
subInfos[i].flags |= typeFlags
|
||||
}
|
||||
paramInfos = append(paramInfos, subInfos...)
|
||||
}
|
||||
return paramInfos
|
||||
default:
|
||||
return []paramInfo{
|
||||
{
|
||||
llvmType: t,
|
||||
name: name,
|
||||
flags: typeFlags,
|
||||
},
|
||||
}
|
||||
return []paramInfo{c.getParamInfo(t, name, goType)}
|
||||
}
|
||||
}
|
||||
|
||||
// getTypeFlags returns the type flags for a given type. It will not recurse
|
||||
// into sub-types (such as in structs).
|
||||
func getTypeFlags(t types.Type) paramFlags {
|
||||
if t == nil {
|
||||
return 0
|
||||
// getParamInfo collects information about a parameter. For example, if this
|
||||
// parameter is pointer-like, it will also store the element type for the
|
||||
// dereferenceable_or_null attribute.
|
||||
func (c *compilerContext) getParamInfo(t llvm.Type, name string, goType types.Type) paramInfo {
|
||||
info := paramInfo{
|
||||
llvmType: t,
|
||||
name: name,
|
||||
}
|
||||
switch t.Underlying().(type) {
|
||||
if goType != nil {
|
||||
switch underlying := goType.Underlying().(type) {
|
||||
case *types.Pointer:
|
||||
// Pointers in Go must either point to an object or be nil.
|
||||
return paramIsDeferenceableOrNull
|
||||
case *types.Chan, *types.Map:
|
||||
// Channels and maps are implemented as pointers pointing to some
|
||||
// object, and follow the same rules as *types.Pointer.
|
||||
return paramIsDeferenceableOrNull
|
||||
default:
|
||||
return 0
|
||||
info.elemSize = c.targetData.TypeAllocSize(c.getLLVMType(underlying.Elem()))
|
||||
case *types.Chan:
|
||||
// Channels are implemented simply as a *runtime.channel.
|
||||
info.elemSize = c.targetData.TypeAllocSize(c.getLLVMRuntimeType("channel"))
|
||||
case *types.Map:
|
||||
// Maps are similar to channels: they are implemented as a
|
||||
// *runtime.hashmap.
|
||||
info.elemSize = c.targetData.TypeAllocSize(c.getLLVMRuntimeType("hashmap"))
|
||||
}
|
||||
}
|
||||
return info
|
||||
}
|
||||
|
||||
// extractSubfield extracts a field from a struct, or returns null if this is
|
||||
|
|
|
@ -862,7 +862,7 @@ func (c *compilerContext) createPackage(irbuilder llvm.Builder, pkg *ssa.Package
|
|||
if files, ok := c.embedGlobals[member.Name()]; ok {
|
||||
c.createEmbedGlobal(member, global, files)
|
||||
} else if !info.extern {
|
||||
global.SetInitializer(llvm.ConstNull(global.Type().ElementType()))
|
||||
global.SetInitializer(llvm.ConstNull(global.GlobalValueType()))
|
||||
global.SetVisibility(llvm.HiddenVisibility)
|
||||
if info.section != "" {
|
||||
global.SetSection(info.section)
|
||||
|
@ -1405,7 +1405,7 @@ func (b *builder) createInstruction(instr ssa.Instruction) {
|
|||
b.CreateRet(b.getValue(instr.Results[0]))
|
||||
} else {
|
||||
// Multiple return values. Put them all in a struct.
|
||||
retVal := llvm.ConstNull(b.llvmFn.Type().ElementType().ReturnType())
|
||||
retVal := llvm.ConstNull(b.llvmFn.GlobalValueType().ReturnType())
|
||||
for i, result := range instr.Results {
|
||||
val := b.getValue(result)
|
||||
retVal = b.CreateInsertValue(retVal, val, i, "")
|
||||
|
@ -1444,7 +1444,7 @@ func (b *builder) createBuiltin(argTypes []types.Type, argValues []llvm.Value, c
|
|||
elemsBuf := b.CreateExtractValue(elems, 0, "append.elemsBuf")
|
||||
elemsPtr := b.CreateBitCast(elemsBuf, b.i8ptrType, "append.srcPtr")
|
||||
elemsLen := b.CreateExtractValue(elems, 1, "append.elemsLen")
|
||||
elemType := srcBuf.Type().ElementType()
|
||||
elemType := b.getLLVMType(argTypes[0].Underlying().(*types.Slice).Elem())
|
||||
elemSize := llvm.ConstInt(b.uintptrType, b.targetData.TypeAllocSize(elemType), false)
|
||||
result := b.createRuntimeCall("sliceAppend", []llvm.Value{srcPtr, elemsPtr, srcLen, srcCap, elemsLen, elemSize}, "append.new")
|
||||
newPtr := b.CreateExtractValue(result, 0, "append.newPtr")
|
||||
|
@ -1497,7 +1497,7 @@ func (b *builder) createBuiltin(argTypes []types.Type, argValues []llvm.Value, c
|
|||
srcLen := b.CreateExtractValue(src, 1, "copy.srcLen")
|
||||
dstBuf := b.CreateExtractValue(dst, 0, "copy.dstArray")
|
||||
srcBuf := b.CreateExtractValue(src, 0, "copy.srcArray")
|
||||
elemType := dstBuf.Type().ElementType()
|
||||
elemType := b.getLLVMType(argTypes[0].Underlying().(*types.Slice).Elem())
|
||||
dstBuf = b.CreateBitCast(dstBuf, b.i8ptrType, "copy.dstPtr")
|
||||
srcBuf = b.CreateBitCast(srcBuf, b.i8ptrType, "copy.srcPtr")
|
||||
elemSize := llvm.ConstInt(b.uintptrType, b.targetData.TypeAllocSize(elemType), false)
|
||||
|
@ -1637,7 +1637,8 @@ func (b *builder) createBuiltin(argTypes []types.Type, argValues []llvm.Value, c
|
|||
b.uintptrType,
|
||||
b.uintptrType,
|
||||
}, false))
|
||||
b.createUnsafeSliceCheck(ptr, len, argTypes[1].Underlying().(*types.Basic))
|
||||
elementType := b.getLLVMType(argTypes[0].Underlying().(*types.Pointer).Elem())
|
||||
b.createUnsafeSliceCheck(ptr, len, elementType, argTypes[1].Underlying().(*types.Basic))
|
||||
if len.Type().IntTypeWidth() < b.uintptrType.IntTypeWidth() {
|
||||
// Too small, zero-extend len.
|
||||
len = b.CreateZExt(len, b.uintptrType, "")
|
||||
|
@ -1712,7 +1713,7 @@ func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error)
|
|||
// Eventually we might be able to eliminate this special case
|
||||
// entirely. For details, see:
|
||||
// https://discourse.llvm.org/t/rfc-enabling-wstrict-prototypes-by-default-in-c/60521
|
||||
calleeType = llvm.FunctionType(callee.Type().ElementType().ReturnType(), nil, false)
|
||||
calleeType = llvm.FunctionType(callee.GlobalValueType().ReturnType(), nil, false)
|
||||
callee = llvm.ConstBitCast(callee, llvm.PointerType(calleeType, b.funcPtrAddrSpace))
|
||||
}
|
||||
case *ssa.MakeClosure:
|
||||
|
@ -3095,7 +3096,7 @@ func (b *builder) createUnOp(unop *ssa.UnOp) (llvm.Value, error) {
|
|||
}
|
||||
case token.MUL: // *x, dereference pointer
|
||||
valueType := b.getLLVMType(unop.X.Type().Underlying().(*types.Pointer).Elem())
|
||||
if b.targetData.TypeAllocSize(x.Type().ElementType()) == 0 {
|
||||
if b.targetData.TypeAllocSize(valueType) == 0 {
|
||||
// zero-length data
|
||||
return llvm.ConstNull(valueType), nil
|
||||
} else if strings.HasSuffix(unop.X.String(), "$funcaddr") {
|
||||
|
|
|
@ -73,7 +73,7 @@ func (c *compilerContext) getFuncType(typ *types.Signature) llvm.Type {
|
|||
return c.ctx.StructType([]llvm.Type{c.i8ptrType, c.rawVoidFuncType}, false)
|
||||
}
|
||||
|
||||
// getRawFuncType returns a LLVM function pointer type for a given signature.
|
||||
// getRawFuncType returns a LLVM function type for a given signature.
|
||||
func (c *compilerContext) getRawFuncType(typ *types.Signature) llvm.Type {
|
||||
// Get the return type.
|
||||
var returnType llvm.Type
|
||||
|
|
|
@ -86,7 +86,7 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
|
|||
if _, ok := typ.Underlying().(*types.Pointer); !ok {
|
||||
ptrTo = c.getTypeCode(types.NewPointer(typ))
|
||||
}
|
||||
globalValue := llvm.ConstNull(global.Type().ElementType())
|
||||
globalValue := llvm.ConstNull(global.GlobalValueType())
|
||||
if !references.IsNil() {
|
||||
globalValue = c.builder.CreateInsertValue(globalValue, references, 0, "")
|
||||
}
|
||||
|
@ -533,7 +533,7 @@ func (c *compilerContext) getInterfaceInvokeWrapper(fn *ssa.Function, llvmFnType
|
|||
|
||||
receiverValue := b.emitPointerUnpack(wrapper.Param(0), []llvm.Type{receiverType})[0]
|
||||
params := append(b.expandFormalParam(receiverValue), wrapper.Params()[1:]...)
|
||||
if llvmFn.Type().ElementType().ReturnType().TypeKind() == llvm.VoidTypeKind {
|
||||
if llvmFnType.ReturnType().TypeKind() == llvm.VoidTypeKind {
|
||||
b.CreateCall(llvmFnType, llvmFn, params, "")
|
||||
b.CreateRetVoid()
|
||||
} else {
|
||||
|
|
|
@ -70,10 +70,7 @@ func (c *checker) checkType(t llvm.Type, checked map[llvm.Type]struct{}, special
|
|||
return fmt.Errorf("failed to verify element type of array type %s: %s", t.String(), err.Error())
|
||||
}
|
||||
case llvm.PointerTypeKind:
|
||||
// check underlying type
|
||||
if err := c.checkType(t.ElementType(), checked, specials); err != nil {
|
||||
return fmt.Errorf("failed to verify underlying type of pointer type %s: %s", t.String(), err.Error())
|
||||
}
|
||||
// Pointers can't be checked in an opaque pointer world.
|
||||
case llvm.VectorTypeKind:
|
||||
// check element type
|
||||
if err := c.checkType(t.ElementType(), checked, specials); err != nil {
|
||||
|
|
|
@ -83,7 +83,7 @@ func (c *compilerContext) getFunction(fn *ssa.Function) (llvm.Type, llvm.Value)
|
|||
// Add an extra parameter as the function context. This context is used in
|
||||
// closures and bound methods, but should be optimized away when not used.
|
||||
if !info.exported {
|
||||
paramInfos = append(paramInfos, paramInfo{llvmType: c.i8ptrType, name: "context", flags: 0})
|
||||
paramInfos = append(paramInfos, paramInfo{llvmType: c.i8ptrType, name: "context", elemSize: 0})
|
||||
}
|
||||
|
||||
var paramTypes []llvm.Type
|
||||
|
@ -112,17 +112,8 @@ func (c *compilerContext) getFunction(fn *ssa.Function) (llvm.Type, llvm.Value)
|
|||
|
||||
dereferenceableOrNullKind := llvm.AttributeKindID("dereferenceable_or_null")
|
||||
for i, info := range paramInfos {
|
||||
if info.flags¶mIsDeferenceableOrNull == 0 {
|
||||
continue
|
||||
}
|
||||
if info.llvmType.TypeKind() == llvm.PointerTypeKind {
|
||||
el := info.llvmType.ElementType()
|
||||
size := c.targetData.TypeAllocSize(el)
|
||||
if size == 0 {
|
||||
// dereferenceable_or_null(0) appears to be illegal in LLVM.
|
||||
continue
|
||||
}
|
||||
dereferenceableOrNull := c.ctx.CreateEnumAttribute(dereferenceableOrNullKind, size)
|
||||
if info.elemSize != 0 {
|
||||
dereferenceableOrNull := c.ctx.CreateEnumAttribute(dereferenceableOrNullKind, info.elemSize)
|
||||
llvmFn.AddAttributeAtIndex(i+1, dereferenceableOrNull)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -209,7 +209,7 @@ func (r *runner) compileFunction(llvmFn llvm.Value) *function {
|
|||
case llvm.Alloca:
|
||||
// Alloca allocates stack space for local variables.
|
||||
numElements := r.getValue(inst.llvmInst.Operand(0)).(literalValue).value.(uint32)
|
||||
elementSize := r.targetData.TypeAllocSize(inst.llvmInst.Type().ElementType())
|
||||
elementSize := r.targetData.TypeAllocSize(inst.llvmInst.AllocatedType())
|
||||
inst.operands = []value{
|
||||
literalValue{elementSize * uint64(numElements)},
|
||||
}
|
||||
|
@ -218,17 +218,17 @@ func (r *runner) compileFunction(llvmFn llvm.Value) *function {
|
|||
inst.name = llvmInst.Name()
|
||||
ptr := llvmInst.Operand(0)
|
||||
n := llvmInst.OperandsCount()
|
||||
elementType := ptr.Type().ElementType()
|
||||
elementType := llvmInst.GEPSourceElementType()
|
||||
// gep: [source ptr, dest value size, pairs of indices...]
|
||||
inst.operands = []value{
|
||||
r.getValue(ptr),
|
||||
literalValue{r.targetData.TypeAllocSize(llvmInst.Type().ElementType())},
|
||||
r.getValue(llvmInst.Operand(1)),
|
||||
literalValue{r.targetData.TypeAllocSize(elementType)},
|
||||
}
|
||||
for i := 2; i < n; i++ {
|
||||
operand := r.getValue(llvmInst.Operand(i))
|
||||
if elementType.TypeKind() == llvm.StructTypeKind {
|
||||
switch elementType.TypeKind() {
|
||||
case llvm.StructTypeKind:
|
||||
index := operand.(literalValue).value.(uint32)
|
||||
elementOffset := r.targetData.ElementOffset(elementType, int(index))
|
||||
// Encode operands in a special way. The elementOffset
|
||||
|
@ -242,12 +242,15 @@ func (r *runner) compileFunction(llvmFn llvm.Value) *function {
|
|||
// runtime.
|
||||
inst.operands = append(inst.operands, literalValue{elementOffset}, literalValue{^uint64(index)})
|
||||
elementType = elementType.StructElementTypes()[index]
|
||||
} else {
|
||||
case llvm.ArrayTypeKind:
|
||||
elementType = elementType.ElementType()
|
||||
elementSize := r.targetData.TypeAllocSize(elementType)
|
||||
elementSizeOperand := literalValue{elementSize}
|
||||
// Add operand * elementSizeOperand bytes to the pointer.
|
||||
inst.operands = append(inst.operands, operand, elementSizeOperand)
|
||||
default:
|
||||
// This should be unreachable.
|
||||
panic("unknown type: " + elementType.String())
|
||||
}
|
||||
}
|
||||
case llvm.BitCast, llvm.IntToPtr, llvm.PtrToInt:
|
||||
|
@ -267,10 +270,12 @@ func (r *runner) compileFunction(llvmFn llvm.Value) *function {
|
|||
case llvm.StructTypeKind:
|
||||
offset += r.targetData.ElementOffset(indexingType, int(index))
|
||||
indexingType = indexingType.StructElementTypes()[index]
|
||||
default: // ArrayTypeKind
|
||||
case llvm.ArrayTypeKind:
|
||||
indexingType = indexingType.ElementType()
|
||||
elementSize := r.targetData.TypeAllocSize(indexingType)
|
||||
offset += elementSize * uint64(index)
|
||||
default:
|
||||
panic("unknown type kind") // unreachable
|
||||
}
|
||||
}
|
||||
size := r.targetData.TypeAllocSize(inst.llvmInst.Type())
|
||||
|
@ -290,10 +295,12 @@ func (r *runner) compileFunction(llvmFn llvm.Value) *function {
|
|||
case llvm.StructTypeKind:
|
||||
offset += r.targetData.ElementOffset(indexingType, int(index))
|
||||
indexingType = indexingType.StructElementTypes()[index]
|
||||
default: // ArrayTypeKind
|
||||
case llvm.ArrayTypeKind:
|
||||
indexingType = indexingType.ElementType()
|
||||
elementSize := r.targetData.TypeAllocSize(indexingType)
|
||||
offset += elementSize * uint64(index)
|
||||
default:
|
||||
panic("unknown type kind") // unreachable
|
||||
}
|
||||
}
|
||||
// insertvalue [agg, elt, byteOffset]
|
||||
|
|
|
@ -156,7 +156,7 @@ func Run(mod llvm.Module, timeout time.Duration, debug bool) error {
|
|||
if obj.constant {
|
||||
continue // constant buffers can't have been modified
|
||||
}
|
||||
initializer, err := obj.buffer.toLLVMValue(obj.llvmGlobal.Type().ElementType(), &mem)
|
||||
initializer, err := obj.buffer.toLLVMValue(obj.llvmGlobal.GlobalValueType(), &mem)
|
||||
if err == errInvalidPtrToIntSize {
|
||||
// This can happen when a previous interp run did not have the
|
||||
// correct LLVM type for a global and made something up. In that
|
||||
|
@ -190,7 +190,7 @@ func Run(mod llvm.Module, timeout time.Duration, debug bool) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if checks && initializer.Type() != obj.llvmGlobal.Type().ElementType() {
|
||||
if checks && initializer.Type() != obj.llvmGlobal.GlobalValueType() {
|
||||
panic("initializer type mismatch")
|
||||
}
|
||||
obj.llvmGlobal.SetInitializer(initializer)
|
||||
|
@ -213,7 +213,7 @@ func RunFunc(fn llvm.Value, timeout time.Duration, debug bool) error {
|
|||
r.pkgName = initName[:len(initName)-len(".init")]
|
||||
|
||||
// Create new function with the interp result.
|
||||
newFn := llvm.AddFunction(mod, fn.Name()+".tmp", fn.Type().ElementType())
|
||||
newFn := llvm.AddFunction(mod, fn.Name()+".tmp", fn.GlobalValueType())
|
||||
newFn.SetLinkage(fn.Linkage())
|
||||
newFn.SetVisibility(fn.Visibility())
|
||||
entry := mod.Context().AddBasicBlock(newFn, "entry")
|
||||
|
@ -263,11 +263,11 @@ func RunFunc(fn llvm.Value, timeout time.Duration, debug bool) error {
|
|||
if obj.constant {
|
||||
continue // constant, so can't have been modified
|
||||
}
|
||||
initializer, err := obj.buffer.toLLVMValue(obj.llvmGlobal.Type().ElementType(), &mem)
|
||||
initializer, err := obj.buffer.toLLVMValue(obj.llvmGlobal.GlobalValueType(), &mem)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if checks && initializer.Type() != obj.llvmGlobal.Type().ElementType() {
|
||||
if checks && initializer.Type() != obj.llvmGlobal.GlobalValueType() {
|
||||
panic("initializer type mismatch")
|
||||
}
|
||||
obj.llvmGlobal.SetInitializer(initializer)
|
||||
|
|
|
@ -655,7 +655,7 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
|
|||
// GetElementPtr does pointer arithmetic, changing the offset of the
|
||||
// pointer into the underlying object.
|
||||
var offset uint64
|
||||
for i := 2; i < len(operands); i += 2 {
|
||||
for i := 1; i < len(operands); i += 2 {
|
||||
index := operands[i].Uint()
|
||||
elementSize := operands[i+1].Uint()
|
||||
if int64(elementSize) < 0 {
|
||||
|
|
|
@ -808,16 +808,19 @@ func (v rawValue) rawLLVMValue(mem *memoryView) (llvm.Value, error) {
|
|||
if err != nil {
|
||||
return llvm.Value{}, err
|
||||
}
|
||||
elementType := field.Type().ElementType()
|
||||
if !field.IsAGlobalVariable().IsNil() {
|
||||
elementType := field.GlobalValueType()
|
||||
if elementType.TypeKind() == llvm.StructTypeKind {
|
||||
// There are some special pointer types that should be used as a
|
||||
// ptrtoint, so that they can be used in certain optimizations.
|
||||
// There are some special pointer types that should be used
|
||||
// as a ptrtoint, so that they can be used in certain
|
||||
// optimizations.
|
||||
name := elementType.StructName()
|
||||
if name == "runtime.typecodeID" || name == "runtime.funcValueWithSignature" {
|
||||
uintptrType := ctx.IntType(int(mem.r.pointerSize) * 8)
|
||||
field = llvm.ConstPtrToInt(field, uintptrType)
|
||||
}
|
||||
}
|
||||
}
|
||||
structFields = append(structFields, field)
|
||||
i += mem.r.pointerSize
|
||||
continue
|
||||
|
@ -998,7 +1001,7 @@ func (v *rawValue) set(llvmValue llvm.Value, r *runner) {
|
|||
ptr := llvmValue.Operand(0)
|
||||
index := llvmValue.Operand(1)
|
||||
numOperands := llvmValue.OperandsCount()
|
||||
elementType := ptr.Type().ElementType()
|
||||
elementType := llvmValue.GEPSourceElementType()
|
||||
totalOffset := r.targetData.TypeAllocSize(elementType) * index.ZExtValue()
|
||||
for i := 2; i < numOperands; i++ {
|
||||
indexValue := llvmValue.Operand(i)
|
||||
|
@ -1173,7 +1176,7 @@ func (r *runner) getValue(llvmValue llvm.Value) value {
|
|||
r.globals[llvmValue] = index
|
||||
r.objects = append(r.objects, obj)
|
||||
if !llvmValue.IsAGlobalVariable().IsNil() {
|
||||
obj.size = uint32(r.targetData.TypeAllocSize(llvmValue.Type().ElementType()))
|
||||
obj.size = uint32(r.targetData.TypeAllocSize(llvmValue.GlobalValueType()))
|
||||
if initializer := llvmValue.Initializer(); !initializer.IsNil() {
|
||||
obj.buffer = r.getValue(initializer)
|
||||
obj.constant = llvmValue.IsGlobalConstant()
|
||||
|
|
|
@ -124,7 +124,7 @@ func OptimizeAllocs(mod llvm.Module, printAllocs *regexp.Regexp, logger func(tok
|
|||
alloca.SetAlignment(alignment)
|
||||
|
||||
// Zero the allocation inside the block where the value was originally allocated.
|
||||
zero := llvm.ConstNull(alloca.Type().ElementType())
|
||||
zero := llvm.ConstNull(alloca.AllocatedType())
|
||||
builder.SetInsertPointBefore(bitcast)
|
||||
store := builder.CreateStore(zero, alloca)
|
||||
store.SetAlignment(alignment)
|
||||
|
|
|
@ -18,7 +18,7 @@ func MakeGCStackSlots(mod llvm.Module) bool {
|
|||
stackChainStart := mod.NamedGlobal("runtime.stackChainStart")
|
||||
if !stackChainStart.IsNil() {
|
||||
stackChainStart.SetLinkage(llvm.InternalLinkage)
|
||||
stackChainStart.SetInitializer(llvm.ConstNull(stackChainStart.Type().ElementType()))
|
||||
stackChainStart.SetInitializer(llvm.ConstNull(stackChainStart.GlobalValueType()))
|
||||
stackChainStart.SetGlobalConstant(true)
|
||||
}
|
||||
return false
|
||||
|
@ -96,7 +96,7 @@ func MakeGCStackSlots(mod llvm.Module) bool {
|
|||
return false
|
||||
}
|
||||
stackChainStart.SetLinkage(llvm.InternalLinkage)
|
||||
stackChainStartType := stackChainStart.Type().ElementType()
|
||||
stackChainStartType := stackChainStart.GlobalValueType()
|
||||
stackChainStart.SetInitializer(llvm.ConstNull(stackChainStartType))
|
||||
|
||||
// Iterate until runtime.trackPointer has no uses left.
|
||||
|
|
|
@ -423,7 +423,7 @@ func (p *lowerInterfacesPass) defineInterfaceImplementsFunc(fn llvm.Value, itf *
|
|||
func (p *lowerInterfacesPass) defineInterfaceMethodFunc(fn llvm.Value, itf *interfaceInfo, signature *signatureInfo) {
|
||||
context := fn.LastParam()
|
||||
actualType := llvm.PrevParam(context)
|
||||
returnType := fn.Type().ElementType().ReturnType()
|
||||
returnType := fn.GlobalValueType().ReturnType()
|
||||
context.SetName("context")
|
||||
actualType.SetName("actualType")
|
||||
fn.SetLinkage(llvm.InternalLinkage)
|
||||
|
|
|
@ -66,7 +66,7 @@ func getGlobalBytes(global llvm.Value, builder llvm.Builder) []byte {
|
|||
// function used for creating reflection sidetables, for example.
|
||||
func replaceGlobalIntWithArray(mod llvm.Module, name string, buf interface{}) llvm.Value {
|
||||
oldGlobal := mod.NamedGlobal(name)
|
||||
globalType, global := makeGlobalArray(mod, buf, name+".tmp", oldGlobal.Type().ElementType())
|
||||
globalType, global := makeGlobalArray(mod, buf, name+".tmp", oldGlobal.GlobalValueType())
|
||||
gep := llvm.ConstGEP(globalType, global, []llvm.Value{
|
||||
llvm.ConstInt(mod.Context().Int32Type(), 0, false),
|
||||
llvm.ConstInt(mod.Context().Int32Type(), 0, false),
|
||||
|
|
|
@ -50,7 +50,7 @@ func ExternalInt64AsPtr(mod llvm.Module, config *compileopts.Config) error {
|
|||
paramTypes := []llvm.Type{}
|
||||
|
||||
// Check return type for 64-bit integer.
|
||||
fnType := fn.Type().ElementType()
|
||||
fnType := fn.GlobalValueType()
|
||||
returnType := fnType.ReturnType()
|
||||
if returnType == int64Type {
|
||||
hasInt64 = true
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче