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.
This commit is contained in:
Ayke van Laethem
2020-03-24 15:29:31 +01:00
committed by Ron Evans
parent b4dddfe439
commit 3b1759f463
+21 -24
View File
@@ -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()
} }