tinygo/0014-all-remove-pointer-ElementType-calls.patch
2022-10-24 05:50:05 -04:00

586 lines
26 KiB
Diff

From 0cdaa0f6db40e372db24d945b557d03b97ff92e9 Mon Sep 17 00:00:00 2001
From: Ayke van Laethem <aykevanlaethem@gmail.com>
Date: Thu, 22 Sep 2022 13:33:00 +0200
Subject: [PATCH 14/18] all: remove pointer ElementType calls
This is needed for opaque pointers, which are enabled by default in
LLVM 15.
Signed-off-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
---
builder/build.go | 4 +--
compiler/asserts.go | 4 +--
compiler/calls.go | 58 ++++++++++++++-------------------
compiler/compiler.go | 15 +++++----
compiler/func.go | 2 +-
compiler/interface.go | 4 +--
compiler/ircheck/check.go | 5 +--
compiler/symbol.go | 15 ++-------
interp/compiler.go | 21 ++++++++----
interp/interp.go | 10 +++---
interp/interpreter.go | 2 +-
interp/memory.go | 23 +++++++------
transform/allocs.go | 2 +-
transform/gc.go | 4 +--
transform/interface-lowering.go | 2 +-
transform/llvm.go | 2 +-
transform/wasm-abi.go | 2 +-
17 files changed, 82 insertions(+), 93 deletions(-)
diff --git a/builder/build.go b/builder/build.go
index 7a7dd9ac..488ee823 100644
--- a/builder/build.go
+++ b/builder/build.go
@@ -418,7 +418,7 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(Buil
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)
@@ -1134,7 +1134,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)
}
diff --git a/compiler/asserts.go b/compiler/asserts.go
index 2a5265e9..ba482494 100644
--- a/compiler/asserts.go
+++ b/compiler/asserts.go
@@ -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
diff --git a/compiler/calls.go b/compiler/calls.go
index b38d770f..b122f0c8 100644
--- a/compiler/calls.go
+++ b/compiler/calls.go
@@ -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) {
- 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
+ if goType != nil {
+ switch underlying := goType.Underlying().(type) {
+ case *types.Pointer:
+ // Pointers in Go must either point to an object or be nil.
+ 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
diff --git a/compiler/compiler.go b/compiler/compiler.go
index 3d29628c..fc47c29c 100644
--- a/compiler/compiler.go
+++ b/compiler/compiler.go
@@ -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") {
diff --git a/compiler/func.go b/compiler/func.go
index c6a8802d..4203fdf7 100644
--- a/compiler/func.go
+++ b/compiler/func.go
@@ -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
diff --git a/compiler/interface.go b/compiler/interface.go
index 106c327a..2007b7d7 100644
--- a/compiler/interface.go
+++ b/compiler/interface.go
@@ -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 {
diff --git a/compiler/ircheck/check.go b/compiler/ircheck/check.go
index 30c6ee17..e2b7ed51 100644
--- a/compiler/ircheck/check.go
+++ b/compiler/ircheck/check.go
@@ -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 {
diff --git a/compiler/symbol.go b/compiler/symbol.go
index 83fe050b..01b3fc37 100644
--- a/compiler/symbol.go
+++ b/compiler/symbol.go
@@ -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&paramIsDeferenceableOrNull == 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)
}
}
diff --git a/interp/compiler.go b/interp/compiler.go
index 20723c64..ffef69e5 100644
--- a/interp/compiler.go
+++ b/interp/compiler.go
@@ -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]
diff --git a/interp/interp.go b/interp/interp.go
index 856f08b1..7833dfe9 100644
--- a/interp/interp.go
+++ b/interp/interp.go
@@ -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)
diff --git a/interp/interpreter.go b/interp/interpreter.go
index 8c783a70..c438b4b6 100644
--- a/interp/interpreter.go
+++ b/interp/interpreter.go
@@ -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 {
diff --git a/interp/memory.go b/interp/memory.go
index 6a537bad..82ab716d 100644
--- a/interp/memory.go
+++ b/interp/memory.go
@@ -808,14 +808,17 @@ func (v rawValue) rawLLVMValue(mem *memoryView) (llvm.Value, error) {
if err != nil {
return llvm.Value{}, err
}
- elementType := field.Type().ElementType()
- 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.
- name := elementType.StructName()
- if name == "runtime.typecodeID" || name == "runtime.funcValueWithSignature" {
- uintptrType := ctx.IntType(int(mem.r.pointerSize) * 8)
- field = llvm.ConstPtrToInt(field, uintptrType)
+ 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.
+ 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)
@@ -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()
diff --git a/transform/allocs.go b/transform/allocs.go
index af7c70b2..5be7df2d 100644
--- a/transform/allocs.go
+++ b/transform/allocs.go
@@ -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)
diff --git a/transform/gc.go b/transform/gc.go
index 514fb1bf..e2d23987 100644
--- a/transform/gc.go
+++ b/transform/gc.go
@@ -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.
diff --git a/transform/interface-lowering.go b/transform/interface-lowering.go
index f28443dc..9e2ffa90 100644
--- a/transform/interface-lowering.go
+++ b/transform/interface-lowering.go
@@ -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)
diff --git a/transform/llvm.go b/transform/llvm.go
index 17968f8a..7042b32d 100644
--- a/transform/llvm.go
+++ b/transform/llvm.go
@@ -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),
diff --git a/transform/wasm-abi.go b/transform/wasm-abi.go
index 064e38f4..83a16d85 100644
--- a/transform/wasm-abi.go
+++ b/transform/wasm-abi.go
@@ -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
--
2.36.1