compiler: optimize comparing interface values against nil
This is a very common case. Avoiding a runtime.interfaceEqual call leads to a very big reduction in code size in some cases (while it doesn't affect many other examples). A number of driver smoke tests are reduced by about 4kB just with this optimization. I found this issue while looking into automatically calculating the required amount of stack space for goroutines. The runtime.interfaceEqual function is recursive, so it is best avoided.
Этот коммит содержится в:
родитель
f06d7d1bd6
коммит
46345aade6
1 изменённых файлов: 13 добавлений и 1 удалений
|
@ -2207,7 +2207,19 @@ func (b *builder) createBinOp(op token.Token, typ, ytyp types.Type, x, y llvm.Va
|
||||||
case *types.Interface:
|
case *types.Interface:
|
||||||
switch op {
|
switch op {
|
||||||
case token.EQL, token.NEQ: // ==, !=
|
case token.EQL, token.NEQ: // ==, !=
|
||||||
result := b.createRuntimeCall("interfaceEqual", []llvm.Value{x, y}, "")
|
nilInterface := llvm.ConstNull(x.Type())
|
||||||
|
var result llvm.Value
|
||||||
|
if x == nilInterface || y == nilInterface {
|
||||||
|
// An interface value is compared against nil.
|
||||||
|
// This is a very common case and is easy to optimize: simply
|
||||||
|
// compare the typecodes (of which one is nil).
|
||||||
|
typecodeX := b.CreateExtractValue(x, 0, "")
|
||||||
|
typecodeY := b.CreateExtractValue(y, 0, "")
|
||||||
|
result = b.CreateICmp(llvm.IntEQ, typecodeX, typecodeY, "")
|
||||||
|
} else {
|
||||||
|
// Fall back to a full interface comparison.
|
||||||
|
result = b.createRuntimeCall("interfaceEqual", []llvm.Value{x, y}, "")
|
||||||
|
}
|
||||||
if op == token.NEQ {
|
if op == token.NEQ {
|
||||||
result = b.CreateNot(result, "")
|
result = b.CreateNot(result, "")
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче