all: remove LLVM 14 support

This is a big change: apart from removing LLVM 14 it also removes typed
pointer support (which was only fully supported in LLVM up to version
14). This removes about 200 lines of code, but more importantly removes
a ton of special cases for LLVM 14.
This commit is contained in:
Ayke van Laethem
2023-09-18 17:54:29 +02:00
committed by Ayke
parent c9721197d5
commit 1da1abe314
33 changed files with 247 additions and 467 deletions
+4 -5
View File
@@ -37,7 +37,7 @@ func OptimizeAllocs(mod llvm.Module, printAllocs *regexp.Regexp, logger func(tok
targetData := llvm.NewTargetData(mod.DataLayout())
defer targetData.Dispose()
i8ptrType := llvm.PointerType(mod.Context().Int8Type(), 0)
ptrType := llvm.PointerType(mod.Context().Int8Type(), 0)
builder := mod.Context().NewBuilder()
defer builder.Dispose()
@@ -110,7 +110,7 @@ func OptimizeAllocs(mod llvm.Module, printAllocs *regexp.Regexp, logger func(tok
} else {
alignment = 8
}
if pointerAlignment := targetData.ABITypeAlignment(i8ptrType); pointerAlignment < alignment {
if pointerAlignment := targetData.ABITypeAlignment(ptrType); pointerAlignment < alignment {
// Use min(alignment, alignof(void*)) as the alignment.
alignment = pointerAlignment
}
@@ -120,7 +120,7 @@ func OptimizeAllocs(mod llvm.Module, printAllocs *regexp.Regexp, logger func(tok
fn := bitcast.InstructionParent().Parent()
builder.SetInsertPointBefore(fn.EntryBasicBlock().FirstInstruction())
allocaType := llvm.ArrayType(mod.Context().Int8Type(), int(size))
alloca := builder.CreateAlloca(allocaType, "stackalloc.alloca")
alloca := builder.CreateAlloca(allocaType, "stackalloc")
alloca.SetAlignment(alignment)
// Zero the allocation inside the block where the value was originally allocated.
@@ -130,8 +130,7 @@ func OptimizeAllocs(mod llvm.Module, printAllocs *regexp.Regexp, logger func(tok
store.SetAlignment(alignment)
// Replace heap alloc bitcast with stack alloc bitcast.
stackalloc := builder.CreateBitCast(alloca, bitcast.Type(), "stackalloc")
bitcast.ReplaceAllUsesWith(stackalloc)
bitcast.ReplaceAllUsesWith(alloca)
if heapalloc != bitcast {
bitcast.EraseFromParentAsInstruction()
}
+1 -2
View File
@@ -225,8 +225,7 @@ func MakeGCStackSlots(mod llvm.Module) bool {
llvm.ConstInt(ctx.Int32Type(), 0, false),
}, "")
builder.CreateStore(parent, gep)
stackObjectCast := builder.CreateBitCast(stackObject, stackChainStartType, "")
builder.CreateStore(stackObjectCast, stackChainStart)
builder.CreateStore(stackObject, stackChainStart)
// Do a store to the stack object after each new pointer that is created.
pointerStores := make(map[llvm.Value]struct{})
+7 -24
View File
@@ -92,7 +92,7 @@ type lowerInterfacesPass struct {
ctx llvm.Context
uintptrType llvm.Type
targetData llvm.TargetData
i8ptrType llvm.Type
ptrType llvm.Type
types map[string]*typeInfo
signatures map[string]*signatureInfo
interfaces map[string]*interfaceInfo
@@ -113,7 +113,7 @@ func LowerInterfaces(mod llvm.Module, config *compileopts.Config) error {
ctx: ctx,
targetData: targetData,
uintptrType: mod.Context().IntType(targetData.PointerSize() * 8),
i8ptrType: llvm.PointerType(ctx.Int8Type(), 0),
ptrType: llvm.PointerType(ctx.Int8Type(), 0),
types: make(map[string]*typeInfo),
signatures: make(map[string]*signatureInfo),
interfaces: make(map[string]*interfaceInfo),
@@ -356,11 +356,9 @@ func (p *lowerInterfacesPass) run() error {
}
// Fallback.
if hasUses(t.typecode) {
bitcast := llvm.ConstBitCast(newGlobal, p.i8ptrType)
negativeOffset := -int64(p.targetData.TypeAllocSize(p.i8ptrType))
gep := p.builder.CreateInBoundsGEP(p.ctx.Int8Type(), bitcast, []llvm.Value{llvm.ConstInt(p.ctx.Int32Type(), uint64(negativeOffset), true)}, "")
bitcast2 := llvm.ConstBitCast(gep, t.typecode.Type())
t.typecode.ReplaceAllUsesWith(bitcast2)
negativeOffset := -int64(p.targetData.TypeAllocSize(p.ptrType))
gep := p.builder.CreateInBoundsGEP(p.ctx.Int8Type(), newGlobal, []llvm.Value{llvm.ConstInt(p.ctx.Int32Type(), uint64(negativeOffset), true)}, "")
t.typecode.ReplaceAllUsesWith(gep)
}
t.typecode.EraseFromParentAsGlobal()
newGlobal.SetName(typecodeName)
@@ -514,7 +512,7 @@ func (p *lowerInterfacesPass) defineInterfaceMethodFunc(fn llvm.Value, itf *inte
params[i] = fn.Param(i + 1)
}
params = append(params,
llvm.Undef(p.i8ptrType),
llvm.Undef(p.ptrType),
)
// Start chain in the entry block.
@@ -554,27 +552,12 @@ func (p *lowerInterfacesPass) defineInterfaceMethodFunc(fn llvm.Value, itf *inte
p.builder.SetInsertPointAtEnd(bb)
receiver := fn.FirstParam()
if receiver.Type() != function.FirstParam().Type() {
// When the receiver is a pointer, it is not wrapped. This means the
// i8* has to be cast to the correct pointer type of the target
// function.
receiver = p.builder.CreateBitCast(receiver, function.FirstParam().Type(), "")
}
// Check whether the called function has the same signature as would be
// expected from the parameters. This can happen in rare cases when
// named struct types are renamed after merging multiple LLVM modules.
paramTypes := []llvm.Type{receiver.Type()}
for _, param := range params {
paramTypes = append(paramTypes, param.Type())
}
calledFunctionType := function.Type()
functionType := llvm.FunctionType(returnType, paramTypes, false)
sig := llvm.PointerType(functionType, calledFunctionType.PointerAddressSpace())
if sig != function.Type() {
function = p.builder.CreateBitCast(function, sig, "")
}
retval := p.builder.CreateCall(functionType, function, append([]llvm.Value{receiver}, params...), "")
if retval.Type().TypeKind() == llvm.VoidTypeKind {
p.builder.CreateRetVoid()
@@ -596,7 +579,7 @@ func (p *lowerInterfacesPass) defineInterfaceMethodFunc(fn llvm.Value, itf *inte
// method on a nil interface.
nilPanic := p.mod.NamedFunction("runtime.nilPanic")
p.builder.CreateCall(nilPanic.GlobalValueType(), nilPanic, []llvm.Value{
llvm.Undef(p.i8ptrType),
llvm.Undef(p.ptrType),
}, "")
p.builder.CreateUnreachable()
}
+13 -13
View File
@@ -6,18 +6,18 @@ target triple = "armv7m-none-eabi"
declare nonnull ptr @runtime.alloc(i32, ptr)
define void @testInt() {
%stackalloc.alloca = alloca [4 x i8], align 4
store [4 x i8] zeroinitializer, ptr %stackalloc.alloca, align 4
store i32 5, ptr %stackalloc.alloca, align 4
%stackalloc = alloca [4 x i8], align 4
store [4 x i8] zeroinitializer, ptr %stackalloc, align 4
store i32 5, ptr %stackalloc, align 4
ret void
}
define i16 @testArray() {
%stackalloc.alloca = alloca [6 x i8], align 2
store [6 x i8] zeroinitializer, ptr %stackalloc.alloca, align 2
%alloc.1 = getelementptr i16, ptr %stackalloc.alloca, i32 1
%stackalloc = alloca [6 x i8], align 2
store [6 x i8] zeroinitializer, ptr %stackalloc, align 2
%alloc.1 = getelementptr i16, ptr %stackalloc, i32 1
store i16 5, ptr %alloc.1, align 2
%alloc.2 = getelementptr i16, ptr %stackalloc.alloca, i32 2
%alloc.2 = getelementptr i16, ptr %stackalloc, i32 2
%val = load i16, ptr %alloc.2, align 2
ret i16 %val
}
@@ -35,9 +35,9 @@ define void @testEscapingCall2() {
}
define void @testNonEscapingCall() {
%stackalloc.alloca = alloca [4 x i8], align 4
store [4 x i8] zeroinitializer, ptr %stackalloc.alloca, align 4
%val = call ptr @noescapeIntPtr(ptr %stackalloc.alloca)
%stackalloc = alloca [4 x i8], align 4
store [4 x i8] zeroinitializer, ptr %stackalloc, align 4
%val = call ptr @noescapeIntPtr(ptr %stackalloc)
ret void
}
@@ -48,12 +48,12 @@ define ptr @testEscapingReturn() {
define void @testNonEscapingLoop() {
entry:
%stackalloc.alloca = alloca [4 x i8], align 4
%stackalloc = alloca [4 x i8], align 4
br label %loop
loop: ; preds = %loop, %entry
store [4 x i8] zeroinitializer, ptr %stackalloc.alloca, align 4
%ptr = call ptr @noescapeIntPtr(ptr %stackalloc.alloca)
store [4 x i8] zeroinitializer, ptr %stackalloc, align 4
%ptr = call ptr @noescapeIntPtr(ptr %stackalloc)
%result = icmp eq ptr null, %ptr
br i1 %result, label %loop, label %end