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.
Этот коммит содержится в:
родитель
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
предоставленный
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 {
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче