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.
Этот коммит содержится в:
Ayke van Laethem 2021-03-08 14:18:04 +01:00 коммит произвёл Ron Evans
родитель 2709d38d63
коммит 0db4b13e37
2 изменённых файлов: 3 добавлений и 26 удалений

Просмотреть файл

@ -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

26
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 {