transform: fix error in interface lowering pass

It appears that LLVM can sometimes recognize that multiple calls to
runtime.interfaceMethod can be merged into one. When that happens, the
interface lowering pass shows an error as it didn't expect that
situation.

Luckily the fix is very easy.
Этот коммит содержится в:
Ayke van Laethem 2020-03-24 15:29:31 +01:00 коммит произвёл Ron Evans
родитель b4dddfe439
коммит 3b1759f463

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

@ -317,33 +317,30 @@ func (p *lowerInterfacesPass) run() error {
} }
inttoptr := inttoptrs[0] inttoptr := inttoptrs[0]
calls := getUses(inttoptr) calls := getUses(inttoptr)
if len(calls) != 1 || calls[0].IsACallInst().IsNil() { for _, call := range calls {
return errorAt(use, "internal error: expected exactly one call use of runtime.interfaceMethod") // Set up parameters for the call. First copy the regular params...
} params := make([]llvm.Value, call.OperandsCount())
call := calls[0] paramTypes := make([]llvm.Type, len(params))
for i := 0; i < len(params)-1; i++ {
params[i] = call.Operand(i)
paramTypes[i] = params[i].Type()
}
// then add the typecode to the end of the list.
params[len(params)-1] = typecode
paramTypes[len(params)-1] = p.uintptrType
// Set up parameters for the call. First copy the regular params... // Create a function that redirects the call to the destination
params := make([]llvm.Value, call.OperandsCount()) // call, after selecting the right concrete type.
paramTypes := make([]llvm.Type, len(params)) redirector := p.getInterfaceMethodFunc(itf, signature, call.Type(), paramTypes)
for i := 0; i < len(params)-1; i++ {
params[i] = call.Operand(i)
paramTypes[i] = params[i].Type()
}
// then add the typecode to the end of the list.
params[len(params)-1] = typecode
paramTypes[len(params)-1] = p.uintptrType
// Create a function that redirects the call to the destination // Replace the old lookup/inttoptr/call with the new call.
// call, after selecting the right concrete type. p.builder.SetInsertPointBefore(call)
redirector := p.getInterfaceMethodFunc(itf, signature, call.Type(), paramTypes) retval := p.builder.CreateCall(redirector, append(params, llvm.ConstNull(llvm.PointerType(p.ctx.Int8Type(), 0))), "")
if retval.Type().TypeKind() != llvm.VoidTypeKind {
// Replace the old lookup/inttoptr/call with the new call. call.ReplaceAllUsesWith(retval)
p.builder.SetInsertPointBefore(call) }
retval := p.builder.CreateCall(redirector, append(params, llvm.ConstNull(llvm.PointerType(p.ctx.Int8Type(), 0))), "") call.EraseFromParentAsInstruction()
if retval.Type().TypeKind() != llvm.VoidTypeKind {
call.ReplaceAllUsesWith(retval)
} }
call.EraseFromParentAsInstruction()
inttoptr.EraseFromParentAsInstruction() inttoptr.EraseFromParentAsInstruction()
use.EraseFromParentAsInstruction() use.EraseFromParentAsInstruction()
} }