Skip to content

Commit c73e3c1

Browse files
committed
[NFC] Destructure AsyncFunctionPointer in getAsyncFunctionAndSize.
In irgen::getAsyncFunctionAndSize, an AsyncFunctionPointer is destructured into one or both of (1) the underlying function pointer and (2) the async context size. Previously, the underlying function pointer was obtained via calling FunctionPointer::getPointer, which function did the work of casting the function pointer to an AsyncFunctionPointer, loading the relative function address from it, and using that relative address to obtain the function pointer. The size, then, if it was also obtained, was obtained by again casting the function pointer to an AsyncFunctionPointer and loading a field from it. To avoid this repetition, here, the relevant portion of the body of FunctionPointer::getPointer is inlined. Now only a single cast to AsyncFunctionPointerPtrTy is required and one or both fields can be loaded from it. The real benefit of this change is as follows: when these function pointers are authenticated as is required to dereference it on arm64e, the authentication will only need to be performed once rather than once for the function pointer and once for the size.
1 parent b0913fd commit c73e3c1

File tree

1 file changed

+16
-10
lines changed

1 file changed

+16
-10
lines changed

lib/IRGen/GenCall.cpp

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1941,16 +1941,19 @@ std::pair<llvm::Value *, llvm::Value *> irgen::getAsyncFunctionAndSize(
19411941
SmallVector<std::pair<llvm::BasicBlock *, llvm::Value *>, 2> sizePhiValues;
19421942
{ // thin
19431943
IGF.Builder.emitBlock(thinBlock);
1944+
auto *ptr = functionPointer.getRawPointer();
1945+
auto *afpPtr =
1946+
IGF.Builder.CreateBitCast(ptr, IGF.IGM.AsyncFunctionPointerPtrTy);
19441947
if (emitFunction) {
1945-
auto *uncastFnPtr = functionPointer.getPointer(IGF);
1948+
llvm::Value *addrPtr = IGF.Builder.CreateStructGEP(afpPtr, 0);
1949+
auto *uncastFnPtr = IGF.emitLoadOfRelativePointer(
1950+
Address(addrPtr, IGF.IGM.getPointerAlignment()), /*isFar*/ false,
1951+
/*expectedType*/ functionPointer.getFunctionType()->getPointerTo());
19461952
auto *fnPtr = IGF.Builder.CreateBitCast(uncastFnPtr, IGF.IGM.Int8PtrTy);
19471953
fnPhiValues.push_back({thinBlock, fnPtr});
19481954
}
19491955
if (emitSize) {
1950-
auto *ptr = functionPointer.getRawPointer();
1951-
auto *descriptorPtr =
1952-
IGF.Builder.CreateBitCast(ptr, IGF.IGM.AsyncFunctionPointerPtrTy);
1953-
auto *sizePtr = IGF.Builder.CreateStructGEP(descriptorPtr, 1);
1956+
auto *sizePtr = IGF.Builder.CreateStructGEP(afpPtr, 1);
19541957
auto *size =
19551958
IGF.Builder.CreateLoad(sizePtr, IGF.IGM.getPointerAlignment());
19561959
sizePhiValues.push_back({thinBlock, size});
@@ -2026,20 +2029,23 @@ std::pair<llvm::Value *, llvm::Value *> irgen::getAsyncFunctionAndSize(
20262029
case SILFunctionTypeRepresentation::WitnessMethod:
20272030
case SILFunctionTypeRepresentation::Closure:
20282031
case SILFunctionTypeRepresentation::Block: {
2032+
auto *ptr = functionPointer.getRawPointer();
2033+
auto *afpPtr =
2034+
IGF.Builder.CreateBitCast(ptr, IGF.IGM.AsyncFunctionPointerPtrTy);
20292035
llvm::Value *fn = nullptr;
20302036
if (emitFunction) {
2031-
fn = functionPointer.getPointer(IGF);
2037+
llvm::Value *addrPtr = IGF.Builder.CreateStructGEP(afpPtr, 0);
2038+
fn = IGF.emitLoadOfRelativePointer(
2039+
Address(addrPtr, IGF.IGM.getPointerAlignment()), /*isFar*/ false,
2040+
/*expectedType*/ functionPointer.getFunctionType()->getPointerTo());
20322041
}
20332042
llvm::Value *size = nullptr;
20342043
if (emitSize) {
20352044
if (functionPointer.useStaticContextSize()) {
20362045
size = llvm::ConstantInt::get(IGF.IGM.Int32Ty,
20372046
initialContextSize.getValue());
20382047
} else {
2039-
auto *ptr = functionPointer.getRawPointer();
2040-
auto *descriptorPtr =
2041-
IGF.Builder.CreateBitCast(ptr, IGF.IGM.AsyncFunctionPointerPtrTy);
2042-
auto *sizePtr = IGF.Builder.CreateStructGEP(descriptorPtr, 1);
2048+
auto *sizePtr = IGF.Builder.CreateStructGEP(afpPtr, 1);
20432049
size = IGF.Builder.CreateLoad(sizePtr, IGF.IGM.getPointerAlignment());
20442050
}
20452051
}

0 commit comments

Comments
 (0)