mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
IRGen: More refactoring in preparation for emitting async function pointers for dispatch thunks
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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()));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user