IRGen: More refactoring in preparation for emitting async function pointers for dispatch thunks

This commit is contained in:
Slava Pestov
2021-01-22 16:34:13 -05:00
parent c36c32027e
commit 8440a8226f
8 changed files with 44 additions and 26 deletions

View File

@@ -130,8 +130,8 @@ class LinkEntity {
/// is a ConstructorDecl* inside a class. /// is a ConstructorDecl* inside a class.
DispatchThunkInitializer, DispatchThunkInitializer,
/// A method dispatch thunk for an allocating constructor. The pointer is a /// A method dispatch thunk for an allocating constructor. The pointer is
/// ConstructorDecl* inside a protocol or a class. /// a ConstructorDecl* inside a protocol or a class.
DispatchThunkAllocator, DispatchThunkAllocator,
/// A method descriptor. The pointer is a FuncDecl* inside a protocol /// A method descriptor. The pointer is a FuncDecl* inside a protocol
@@ -295,7 +295,7 @@ class LinkEntity {
/// The same as AsyncFunctionPointer but with a different stored value, for /// The same as AsyncFunctionPointer but with a different stored value, for
/// use by TBDGen. /// use by TBDGen.
/// The pointer is a AbstractStorageDecl*. /// The pointer is an AbstractFunctionDecl*.
AsyncFunctionPointerAST, AsyncFunctionPointerAST,
/// The pointer is a SILFunction*. /// The pointer is a SILFunction*.
@@ -861,7 +861,8 @@ public:
} }
static LinkEntity static LinkEntity
forSILFunction(SILFunction *F, bool IsDynamicallyReplaceableImplementation) { forSILFunction(SILFunction *F,
bool IsDynamicallyReplaceableImplementation=false) {
LinkEntity entity; LinkEntity entity;
entity.Pointer = F; entity.Pointer = F;
entity.SecondaryPointer = nullptr; entity.SecondaryPointer = nullptr;
@@ -1100,12 +1101,21 @@ public:
return entity; return entity;
} }
static LinkEntity forAsyncFunctionPointer(SILFunction *silFunction) { static LinkEntity forAsyncFunctionPointer(LinkEntity other) {
LinkEntity entity; LinkEntity entity;
entity.Pointer = silFunction;
entity.SecondaryPointer = nullptr; switch (other.getKind()) {
entity.Data = LINKENTITY_SET_FIELD( case LinkEntity::Kind::SILFunction:
Kind, unsigned(LinkEntity::Kind::AsyncFunctionPointer)); entity.Pointer = other.getSILFunction();
entity.SecondaryPointer = nullptr;
entity.Data = LINKENTITY_SET_FIELD(
Kind, unsigned(LinkEntity::Kind::AsyncFunctionPointer));
break;
default:
llvm_unreachable("Link entity kind cannot have an async function pointer");
}
return entity; return entity;
} }

View File

@@ -174,8 +174,8 @@ namespace irgen {
// Temporary only! // Temporary only!
explicit FunctionPointer(KindTy kind, llvm::Value *value, explicit FunctionPointer(KindTy kind, llvm::Value *value,
const Signature &signature, bool const Signature &signature,
isWithoutCtxt = false) bool isWithoutCtxt = false)
: FunctionPointer(kind, value, PointerAuthInfo(), signature, isWithoutCtxt) {} : FunctionPointer(kind, value, PointerAuthInfo(), signature, isWithoutCtxt) {}
static FunctionPointer forDirect(IRGenModule &IGM, static FunctionPointer forDirect(IRGenModule &IGM,

View File

@@ -920,7 +920,7 @@ emitKeyPathComponent(IRGenModule &IGM,
idKind = KeyPathComponentHeader::Pointer; idKind = KeyPathComponentHeader::Pointer;
// FIXME: Does this need to be signed? // FIXME: Does this need to be signed?
auto idRef = IGM.getAddrOfLLVMVariableOrGOTEquivalent( auto idRef = IGM.getAddrOfLLVMVariableOrGOTEquivalent(
LinkEntity::forSILFunction(id.getFunction(), false)); LinkEntity::forSILFunction(id.getFunction()));
idValue = idRef.getValue(); idValue = idRef.getValue();
// If we got an indirect reference, we'll need to resolve it at // If we got an indirect reference, we'll need to resolve it at

View File

@@ -5353,14 +5353,14 @@ bool irgen::methodRequiresReifiedVTableEntry(IRGenModule &IGM,
} }
llvm::GlobalValue *irgen::emitAsyncFunctionPointer(IRGenModule &IGM, llvm::GlobalValue *irgen::emitAsyncFunctionPointer(IRGenModule &IGM,
SILFunction *function, llvm::Function *function,
LinkEntity entity,
Size size) { Size size) {
ConstantInitBuilder initBuilder(IGM); ConstantInitBuilder initBuilder(IGM);
ConstantStructBuilder builder( ConstantStructBuilder builder(
initBuilder.beginStruct(IGM.AsyncFunctionPointerTy)); initBuilder.beginStruct(IGM.AsyncFunctionPointerTy));
builder.addRelativeAddress( builder.addRelativeAddress(function);
IGM.getAddrOfSILFunction(function, NotForDefinition));
builder.addInt32(size.getValue()); builder.addInt32(size.getValue());
return cast<llvm::GlobalValue>(IGM.defineAsyncFunctionPointer( return cast<llvm::GlobalValue>(IGM.defineAsyncFunctionPointer(
function, builder.finishAndCreateFuture())); entity, builder.finishAndCreateFuture()));
} }

View File

@@ -47,6 +47,7 @@ namespace irgen {
class Size; class Size;
class StructLayout; class StructLayout;
class ClassLayout; class ClassLayout;
class LinkEntity;
bool requiresForeignTypeMetadata(CanType type); bool requiresForeignTypeMetadata(CanType type);
bool requiresForeignTypeMetadata(NominalTypeDecl *decl); bool requiresForeignTypeMetadata(NominalTypeDecl *decl);
@@ -183,7 +184,9 @@ namespace irgen {
ArrayRef<Requirement> requirements); ArrayRef<Requirement> requirements);
llvm::GlobalValue *emitAsyncFunctionPointer(IRGenModule &IGM, llvm::GlobalValue *emitAsyncFunctionPointer(IRGenModule &IGM,
SILFunction *function, Size size); llvm::Function *function,
LinkEntity entity,
Size size);
} // end namespace irgen } // end namespace irgen
} // end namespace swift } // end namespace swift

View File

@@ -165,15 +165,16 @@ void IRGenModule::emitDispatchThunk(SILDeclRef declRef) {
llvm::Constant * llvm::Constant *
IRGenModule::getAddrOfAsyncFunctionPointer(SILFunction *function) { IRGenModule::getAddrOfAsyncFunctionPointer(SILFunction *function) {
(void)getAddrOfSILFunction(function, NotForDefinition); (void)getAddrOfSILFunction(function, NotForDefinition);
auto entity = LinkEntity::forAsyncFunctionPointer(function); auto entity = LinkEntity::forAsyncFunctionPointer(
LinkEntity::forSILFunction(function));
return getAddrOfLLVMVariable(entity, NotForDefinition, DebugTypeInfo()); return getAddrOfLLVMVariable(entity, NotForDefinition, DebugTypeInfo());
} }
llvm::Constant *IRGenModule::defineAsyncFunctionPointer(SILFunction *function, llvm::Constant *IRGenModule::defineAsyncFunctionPointer(LinkEntity entity,
ConstantInit init) { ConstantInit init) {
auto entity = LinkEntity::forAsyncFunctionPointer(function); auto asyncEntity = LinkEntity::forAsyncFunctionPointer(entity);
auto *var = cast<llvm::GlobalVariable>( auto *var = cast<llvm::GlobalVariable>(
getAddrOfLLVMVariable(entity, init, DebugTypeInfo())); getAddrOfLLVMVariable(asyncEntity, init, DebugTypeInfo()));
setTrueConstGlobal(var); setTrueConstGlobal(var);
return var; return var;
} }

View File

@@ -1397,7 +1397,7 @@ public:
llvm::Constant *getOpaquePtr(llvm::Constant *pointer); llvm::Constant *getOpaquePtr(llvm::Constant *pointer);
llvm::Constant *getAddrOfAsyncFunctionPointer(SILFunction *function); llvm::Constant *getAddrOfAsyncFunctionPointer(SILFunction *function);
llvm::Constant *defineAsyncFunctionPointer(SILFunction *function, llvm::Constant *defineAsyncFunctionPointer(LinkEntity entity,
ConstantInit init); ConstantInit init);
SILFunction *getSILFunctionForAsyncFunctionPointer(llvm::Constant *afp); SILFunction *getSILFunctionForAsyncFunctionPointer(llvm::Constant *afp);

View File

@@ -26,6 +26,7 @@
#include "swift/Basic/ExternalUnion.h" #include "swift/Basic/ExternalUnion.h"
#include "swift/Basic/Range.h" #include "swift/Basic/Range.h"
#include "swift/Basic/STLExtras.h" #include "swift/Basic/STLExtras.h"
#include "swift/IRGen/Linking.h"
#include "swift/SIL/ApplySite.h" #include "swift/SIL/ApplySite.h"
#include "swift/SIL/Dominance.h" #include "swift/SIL/Dominance.h"
#include "swift/SIL/InstructionUtils.h" #include "swift/SIL/InstructionUtils.h"
@@ -1943,9 +1944,12 @@ void IRGenSILFunction::emitSILFunction() {
IGM.IRGen.addDynamicReplacement(CurSILFn); IGM.IRGen.addDynamicReplacement(CurSILFn);
auto funcTy = CurSILFn->getLoweredFunctionType(); auto funcTy = CurSILFn->getLoweredFunctionType();
if (funcTy->isAsync() && funcTy->getLanguage() == SILFunctionLanguage::Swift) if (funcTy->isAsync() && funcTy->getLanguage() == SILFunctionLanguage::Swift) {
emitAsyncFunctionPointer(IGM, CurSILFn, emitAsyncFunctionPointer(IGM,
CurFn,
LinkEntity::forSILFunction(CurSILFn),
getAsyncContextLayout(*this).getSize()); getAsyncContextLayout(*this).getSize());
}
// Configure the dominance resolver. // Configure the dominance resolver.
// TODO: consider re-using a dom analysis from the PassManager // TODO: consider re-using a dom analysis from the PassManager
@@ -2278,14 +2282,14 @@ void IRGenSILFunction::visitFunctionRefBaseInst(FunctionRefBaseInst *i) {
auto *fnPtr = IGM.getAddrOfSILFunction( auto *fnPtr = IGM.getAddrOfSILFunction(
fn, NotForDefinition, false /*isDynamicallyReplaceableImplementation*/, fn, NotForDefinition, false /*isDynamicallyReplaceableImplementation*/,
isa<PreviousDynamicFunctionRefInst>(i)); isa<PreviousDynamicFunctionRefInst>(i));
llvm::Value *value; llvm::Constant *value;
auto isSpecialAsyncWithoutCtxtSize = auto isSpecialAsyncWithoutCtxtSize =
fn->isAsync() && ( fn->isAsync() && (
fn->getName().equals("swift_task_future_wait") || fn->getName().equals("swift_task_future_wait") ||
fn->getName().equals("swift_task_group_wait_next")); fn->getName().equals("swift_task_group_wait_next"));
if (fn->isAsync() && !isSpecialAsyncWithoutCtxtSize) { if (fn->isAsync() && !isSpecialAsyncWithoutCtxtSize) {
value = IGM.getAddrOfAsyncFunctionPointer(fn); value = IGM.getAddrOfAsyncFunctionPointer(fn);
value = Builder.CreateBitCast(value, fnPtr->getType()); value = llvm::ConstantExpr::getBitCast(value, fnPtr->getType());
} else { } else {
value = fnPtr; value = fnPtr;
} }