IRGenSIL.cpp (swift-swift-5.8-RELEASE) | : | IRGenSIL.cpp (swift-swift-5.8.1-RELEASE) | ||
---|---|---|---|---|
skipping to change at line 2666 | skipping to change at line 2666 | |||
if (name.equals("swift_taskGroup_waitAll")) | if (name.equals("swift_taskGroup_waitAll")) | |||
return SpecialKind::TaskGroupWaitAll; | return SpecialKind::TaskGroupWaitAll; | |||
if (name.equals("swift_distributed_execute_target")) | if (name.equals("swift_distributed_execute_target")) | |||
return SpecialKind::DistributedExecuteTarget; | return SpecialKind::DistributedExecuteTarget; | |||
} | } | |||
return fn->getLoweredFunctionType(); | return fn->getLoweredFunctionType(); | |||
} | } | |||
// Async functions that end up with weak_odr or linkonce_odr linkage may not be | ||||
// directly called because we need to preserve the connection between the | ||||
// function's implementation and the function's context size in the async | ||||
// function pointer data structure. | ||||
static bool mayDirectlyCallAsync(SILFunction *fn) { | ||||
if (fn->getLinkage() == SILLinkage::Shared || | ||||
fn->getLinkage() == SILLinkage::PublicNonABI) { | ||||
return false; | ||||
} | ||||
return true; | ||||
} | ||||
void IRGenSILFunction::visitFunctionRefBaseInst(FunctionRefBaseInst *i) { | void IRGenSILFunction::visitFunctionRefBaseInst(FunctionRefBaseInst *i) { | |||
auto fn = i->getInitiallyReferencedFunction(); | auto fn = i->getInitiallyReferencedFunction(); | |||
auto fnType = fn->getLoweredFunctionType(); | auto fnType = fn->getLoweredFunctionType(); | |||
auto fpKind = irgen::classifyFunctionPointerKind(fn); | auto fpKind = irgen::classifyFunctionPointerKind(fn); | |||
auto sig = IGM.getSignature(fnType, fpKind); | auto sig = IGM.getSignature(fnType, fpKind); | |||
// Note that the pointer value returned by getAddrOfSILFunction doesn't | // Note that the pointer value returned by getAddrOfSILFunction doesn't | |||
skipping to change at line 2692 | skipping to change at line 2704 | |||
// For ordinary async functions, produce both the async FP and the | // For ordinary async functions, produce both the async FP and the | |||
// direct address of the function. In the common case where we | // direct address of the function. In the common case where we | |||
// directly call the function, we'll want to call the latter rather | // directly call the function, we'll want to call the latter rather | |||
// than indirecting through the async FP. | // than indirecting through the async FP. | |||
llvm::Constant *value; | llvm::Constant *value; | |||
llvm::Constant *secondaryValue; | llvm::Constant *secondaryValue; | |||
if (fpKind.isAsyncFunctionPointer()) { | if (fpKind.isAsyncFunctionPointer()) { | |||
value = IGM.getAddrOfAsyncFunctionPointer(fn); | value = IGM.getAddrOfAsyncFunctionPointer(fn); | |||
value = llvm::ConstantExpr::getBitCast(value, fnPtr->getType()); | value = llvm::ConstantExpr::getBitCast(value, fnPtr->getType()); | |||
secondaryValue = IGM.getAddrOfSILFunction(fn, NotForDefinition); | secondaryValue = mayDirectlyCallAsync(fn) ? | |||
IGM.getAddrOfSILFunction(fn, NotForDefinition) : nullptr; | ||||
// For ordinary sync functions and special async functions, produce | // For ordinary sync functions and special async functions, produce | |||
// only the direct address of the function. The runtime does not | // only the direct address of the function. The runtime does not | |||
// define async FP symbols for the special async functions it defines. | // define async FP symbols for the special async functions it defines. | |||
} else { | } else { | |||
value = fnPtr; | value = fnPtr; | |||
secondaryValue = nullptr; | secondaryValue = nullptr; | |||
} | } | |||
FunctionPointer fp = | FunctionPointer fp = | |||
FunctionPointer::forDirect(fpKind, value, secondaryValue, sig); | FunctionPointer::forDirect(fpKind, value, secondaryValue, sig); | |||
End of changes. 2 change blocks. | ||||
1 lines changed or deleted | 14 lines changed or added |