From 0db4b13e37d4af625ac0956e2560b83c88f01fe1 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Mon, 8 Mar 2021 14:18:04 +0100 Subject: [PATCH] compiler: do not emit nil checks for *ssa.Alloc instructions An allocated object is never nil, so there is no need for a nil check. This probably does not result in any better optimization (the nil check is easily optimized away by LLVM because the result of runtime.alloc is marked nonnull) but it makes the slice tests a bit cleaner. --- compiler/asserts.go | 3 +++ compiler/testdata/slice.ll | 26 -------------------------- 2 files changed, 3 insertions(+), 26 deletions(-) diff --git a/compiler/asserts.go b/compiler/asserts.go index 63f4b90b..1559da76 100644 --- a/compiler/asserts.go +++ b/compiler/asserts.go @@ -159,6 +159,9 @@ func (b *builder) createNilCheck(inst ssa.Value, ptr llvm.Value, blockPrefix str } switch inst := inst.(type) { + case *ssa.Alloc: + // An alloc is never nil. + return case *ssa.IndexAddr: // This pointer is the result of an index operation into a slice or // array. Such slices/arrays are already bounds checked so the pointer diff --git a/compiler/testdata/slice.ll b/compiler/testdata/slice.ll index 4ff983a8..3502851d 100644 --- a/compiler/testdata/slice.ll +++ b/compiler/testdata/slice.ll @@ -40,38 +40,14 @@ declare void @runtime.lookupPanic(i8*, i8*) define hidden { i32*, i32, i32 } @main.sliceAppendValues(i32* %ints.data, i32 %ints.len, i32 %ints.cap, i8* %context, i8* %parentHandle) unnamed_addr { entry: %varargs = call i8* @runtime.alloc(i32 12, i8* undef, i8* null) - br i1 false, label %gep.throw, label %gep.next - -gep.throw: ; preds = %entry - unreachable - -gep.next: ; preds = %entry %0 = bitcast i8* %varargs to i32* store i32 1, i32* %0, align 4 - br i1 false, label %gep.throw1, label %gep.next2 - -gep.throw1: ; preds = %gep.next - unreachable - -gep.next2: ; preds = %gep.next %1 = getelementptr inbounds i8, i8* %varargs, i32 4 %2 = bitcast i8* %1 to i32* store i32 2, i32* %2, align 4 - br i1 false, label %gep.throw3, label %gep.next4 - -gep.throw3: ; preds = %gep.next2 - unreachable - -gep.next4: ; preds = %gep.next2 %3 = getelementptr inbounds i8, i8* %varargs, i32 8 %4 = bitcast i8* %3 to i32* store i32 3, i32* %4, align 4 - br i1 false, label %slice.throw, label %slice.next - -slice.throw: ; preds = %gep.next4 - unreachable - -slice.next: ; preds = %gep.next4 %append.srcPtr = bitcast i32* %ints.data to i8* %append.new = call { i8*, i32, i32 } @runtime.sliceAppend(i8* %append.srcPtr, i8* nonnull %varargs, i32 %ints.len, i32 %ints.cap, i32 3, i32 4, i8* undef, i8* null) %append.newPtr = extractvalue { i8*, i32, i32 } %append.new, 0 @@ -84,8 +60,6 @@ slice.next: ; preds = %gep.next4 ret { i32*, i32, i32 } %7 } -declare void @runtime.nilPanic(i8*, i8*) - declare { i8*, i32, i32 } @runtime.sliceAppend(i8*, i8*, i32, i32, i32, i32, i8*, i8*) define hidden { i32*, i32, i32 } @main.sliceAppendSlice(i32* %ints.data, i32 %ints.len, i32 %ints.cap, i32* %added.data, i32 %added.len, i32 %added.cap, i8* %context, i8* %parentHandle) unnamed_addr {