Skip to content

Improve support in Swift for program address space N in llvm DataLayout #74817

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions include/swift/Runtime/RuntimeFunctions.def
Original file line number Diff line number Diff line change
Expand Up @@ -1595,12 +1595,11 @@ FUNCTION(GetEnumTagSinglePayloadGeneric,
ARGS(OpaquePtrTy, Int32Ty, TypeMetadataPtrTy,
llvm::FunctionType::get(Int32Ty, {OpaquePtrTy, Int32Ty,
TypeMetadataPtrTy},
false)->getPointerTo()),
false)->getPointerTo(DataLayout.getProgramAddressSpace())),
ATTRS(NoUnwind, WillReturn),
EFFECT(NoEffect),
MEMEFFECTS(ReadOnly))


// void swift_storeEnumTagSinglePayloadGeneric(opaque_t *obj,
// unsigned case_index,
// unsigned num_empty_cases,
Expand All @@ -1616,7 +1615,7 @@ FUNCTION(StoreEnumTagSinglePayloadGeneric,
ARGS(OpaquePtrTy, Int32Ty, Int32Ty, TypeMetadataPtrTy,
llvm::FunctionType::get(VoidTy, {OpaquePtrTy, Int32Ty, Int32Ty,
TypeMetadataPtrTy},
false)->getPointerTo()),
false)->getPointerTo(DataLayout.getProgramAddressSpace())),
ATTRS(NoUnwind, WillReturn),
EFFECT(NoEffect),
UNKNOWN_MEMEFFECTS)
Expand Down Expand Up @@ -1890,7 +1889,7 @@ FUNCTION(IsOptionalType,
// void *context);
FUNCTION(Once, swift_once, C_CC, AlwaysAvailable,
RETURNS(VoidTy),
ARGS(OnceTy->getPointerTo(), Int8PtrTy, Int8PtrTy),
ARGS(OnceTy->getPointerTo(), Int8ProgramSpacePtrTy, Int8PtrTy),
ATTRS(NoUnwind),
EFFECT(Locking),
UNKNOWN_MEMEFFECTS)
Expand Down
25 changes: 15 additions & 10 deletions lib/IRGen/GenCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,12 @@ namespace {

/// Add a pointer to the given type as the next parameter.
void addPointerParameter(llvm::Type *storageType) {
ParamIRTypes.push_back(storageType->getPointerTo());
if (isa<llvm::FunctionType>(storageType)) {
// read the program data space from the target data layout
ParamIRTypes.push_back(storageType->getPointerTo(IGM.DataLayout.getProgramAddressSpace()));
} else {
ParamIRTypes.push_back(storageType->getPointerTo());
}
}

void addCoroutineContextParameter();
Expand Down Expand Up @@ -3452,11 +3457,11 @@ llvm::CallBase *CallEmission::emitCallSite() {
auto origCallee = call->getCalledOperand();
llvm::Value *opaqueCallee = origCallee;
opaqueCallee =
IGF.Builder.CreateBitCast(opaqueCallee, IGF.IGM.Int8PtrTy);
IGF.Builder.CreatePointerBitCastOrAddrSpaceCast(opaqueCallee, IGF.IGM.Int8PtrTy);
opaqueCallee = IGF.Builder.CreateIntrinsicCall(
llvm::Intrinsic::coro_prepare_retcon, {opaqueCallee});
opaqueCallee =
IGF.Builder.CreateBitCast(opaqueCallee, origCallee->getType());
IGF.Builder.CreatePointerBitCastOrAddrSpaceCast(opaqueCallee, origCallee->getType());
call->setCalledFunction(fn.getFunctionType(), opaqueCallee);

// Reset the insert point to after the call.
Expand Down Expand Up @@ -4667,11 +4672,11 @@ emitRetconCoroutineEntry(IRGenFunction &IGF, CanSILFunctionType fnType,
llvm::Intrinsic::ID idIntrinsic, Size bufferSize,
Alignment bufferAlignment) {
auto prototype =
IGF.IGM.getOpaquePtr(IGF.IGM.getAddrOfContinuationPrototype(fnType));
IGF.IGM.getOpaquePtrToFn(IGF.IGM.getAddrOfContinuationPrototype(fnType));

// Use malloc and free as our allocator.
auto allocFn = IGF.IGM.getOpaquePtr(IGF.IGM.getMallocFn());
auto deallocFn = IGF.IGM.getOpaquePtr(IGF.IGM.getFreeFn());
auto allocFn = IGF.IGM.getOpaquePtrToFn(IGF.IGM.getMallocFn());
auto deallocFn = IGF.IGM.getOpaquePtrToFn(IGF.IGM.getFreeFn());

// Call the right 'llvm.coro.id.retcon' variant.
llvm::Value *buffer = emission.getCoroutineBuffer();
Expand Down Expand Up @@ -5265,7 +5270,7 @@ llvm::Value* IRGenFunction::coerceValue(llvm::Value *value, llvm::Type *toTy,
// Use the pointer/pointer and pointer/int casts if we can.
if (toTy->isPointerTy()) {
if (fromTy->isPointerTy())
return Builder.CreateBitCast(value, toTy);
return Builder.CreatePointerBitCastOrAddrSpaceCast(value, toTy);
if (fromTy == IGM.IntPtrTy)
return Builder.CreateIntToPtr(value, toTy);
} else if (fromTy->isPointerTy()) {
Expand Down Expand Up @@ -5816,7 +5821,7 @@ Signature irgen::emitCastOfFunctionPointer(IRGenFunction &IGF,
: IGF.IGM.getSignature(fnType);

// Emit the cast.
fnPtr = IGF.Builder.CreateBitCast(fnPtr, sig.getType()->getPointerTo());
fnPtr = IGF.Builder.CreateBitCast(fnPtr, sig.getType()->getPointerTo(IGF.IGM.DataLayout.getProgramAddressSpace()));

// Return the information.
return sig;
Expand Down Expand Up @@ -5949,7 +5954,7 @@ FunctionPointer FunctionPointer::forExplosionValue(IRGenFunction &IGF,
llvm::Value *fnPtr,
CanSILFunctionType fnType) {
// Bitcast out of an opaque pointer type.
assert(fnPtr->getType() == IGF.IGM.Int8PtrTy);
assert(fnPtr->getType() == IGF.IGM.Int8ProgramSpacePtrTy);
auto sig = emitCastOfFunctionPointer(IGF, fnPtr, fnType);
auto authInfo = PointerAuthInfo::forFunctionPointer(IGF.IGM, fnType);

Expand All @@ -5968,7 +5973,7 @@ FunctionPointer::getExplosionValue(IRGenFunction &IGF,
}

// Bitcast to an opaque pointer type.
fnPtr = IGF.Builder.CreateBitCast(fnPtr, IGF.IGM.Int8PtrTy);
fnPtr = IGF.Builder.CreateBitCast(fnPtr, IGF.IGM.Int8ProgramSpacePtrTy);

return fnPtr;
}
Expand Down
9 changes: 8 additions & 1 deletion lib/IRGen/GenDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,10 @@ emitGlobalList(IRGenModule &IGM, ArrayRef<llvm::WeakTrackingVH> handles,
elts.reserve(handles.size());
for (auto &handle : handles) {
auto elt = cast<llvm::Constant>(&*handle);

if (elt->getType()->getPointerAddressSpace()!=0)
continue; // we currently cannot handle multiple address spaces in llvm.used

if (elt->getType() != eltTy)
elt = llvm::ConstantExpr::getBitCast(elt, eltTy);
elts.push_back(elt);
Expand Down Expand Up @@ -2158,7 +2162,9 @@ void IRGenModule::emitVTableStubs() {
// Create a single stub function which calls swift_deletedMethodError().
stub = llvm::Function::Create(llvm::FunctionType::get(VoidTy, false),
llvm::GlobalValue::InternalLinkage,
/*addrspace*/DataLayout.getProgramAddressSpace(),
"_swift_dead_method_stub");
// getModule()); // most places do this, but this doesn't work here because we then try to add the function again two lines down
stub->setAttributes(constructInitialAttributes());
Module.getFunctionList().push_back(stub);
stub->setCallingConv(DefaultCC);
Expand Down Expand Up @@ -2443,7 +2449,8 @@ llvm::Function *irgen::createFunction(IRGenModule &IGM, LinkInfo &linkInfo,
}

llvm::Function *fn =
llvm::Function::Create(signature.getType(), linkInfo.getLinkage(), name);
llvm::Function::Create(signature.getType(), linkInfo.getLinkage(),
/*addrspace*/IGM.DataLayout.getProgramAddressSpace(), name);
fn->setCallingConv(signature.getCallingConv());

if (insertBefore) {
Expand Down
4 changes: 2 additions & 2 deletions lib/IRGen/GenFunc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1861,7 +1861,7 @@ static llvm::Value *emitPartialApplicationForwarder(
}

// Derive the callee function pointer.
auto fnTy = origSig.getType()->getPointerTo();
auto fnTy = origSig.getType()->getPointerTo(IGM.DataLayout.getProgramAddressSpace());
FunctionPointer fnPtr = [&]() -> FunctionPointer {
// If we found a function pointer statically, great.
if (staticFnPtr) {
Expand Down Expand Up @@ -2353,7 +2353,7 @@ std::optional<StackAddress> irgen::emitFunctionPartialApplication(
IGF.IGM, staticFn, fnContext != nullptr, origSig, origType, substType,
outType, subs, &layout, argConventions);
forwarder = emitPointerAuthSign(IGF, forwarder, outAuthInfo);
forwarder = IGF.Builder.CreateBitCast(forwarder, IGF.IGM.Int8PtrTy);
forwarder = IGF.Builder.CreateBitCast(forwarder, IGF.IGM.Int8ProgramSpacePtrTy);
out.add(forwarder);
out.add(data);
return stackAddr;
Expand Down
2 changes: 1 addition & 1 deletion lib/IRGen/GenHeap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -875,7 +875,7 @@ static void emitUnaryRefCountCall(IRGenFunction &IGF,
? IGF.IGM.VoidTy
: value->getType();
fnType = llvm::FunctionType::get(resultTy, value->getType(), false);
fn = llvm::ConstantExpr::getBitCast(fn, fnType->getPointerTo());
fn = llvm::ConstantExpr::getBitCast(fn, fnType->getPointerTo(fn->getType()->getPointerAddressSpace()));
}

// Emit the call.
Expand Down
2 changes: 1 addition & 1 deletion lib/IRGen/GenProto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1567,7 +1567,7 @@ class AccessorConformanceInfo : public ConformanceInfo {
IGM.getDeletedMethodErrorFn(), IGM.FunctionPtrTy);
}
}
witness = llvm::ConstantExpr::getBitCast(witness, IGM.Int8PtrTy);
witness = llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(witness, IGM.Int8PtrTy);

if (isRelative) {
Table.addRelativeAddress(witness);
Expand Down
2 changes: 1 addition & 1 deletion lib/IRGen/GenValueWitness.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1028,7 +1028,7 @@ static void addValueWitness(IRGenModule &IGM, ConstantStructBuilder &B,
const std::optional<BoundGenericTypeCharacteristics>
boundGenericCharacteristics = std::nullopt) {
auto addFunction = [&](llvm::Constant *fn) {
fn = llvm::ConstantExpr::getBitCast(fn, IGM.Int8PtrTy);
fn = llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(fn, IGM.Int8PtrTy);
B.addSignedPointer(fn, IGM.getOptions().PointerAuth.ValueWitnesses, index);
};

Expand Down
7 changes: 4 additions & 3 deletions lib/IRGen/IRGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ IRGenModule::IRGenModule(IRGenerator &irgen,
Int32PtrTy = Int32Ty->getPointerTo();
Int64Ty = llvm::Type::getInt64Ty(getLLVMContext());
Int8PtrTy = llvm::Type::getInt8PtrTy(getLLVMContext());
FunctionPtrTy = llvm::Type::getInt8PtrTy(getLLVMContext(),DataLayout.getProgramAddressSpace());
Int8PtrPtrTy = Int8PtrTy->getPointerTo(0);
SizeTy = DataLayout.getIntPtrType(getLLVMContext(), /*addrspace*/ 0);

Expand Down Expand Up @@ -371,7 +372,7 @@ IRGenModule::IRGenModule(IRGenerator &irgen,
});

DeallocatingDtorTy = llvm::FunctionType::get(VoidTy, RefCountedPtrTy, false);
llvm::Type *dtorPtrTy = DeallocatingDtorTy->getPointerTo();
llvm::Type *dtorPtrTy = DeallocatingDtorTy->getPointerTo(DataLayout.getProgramAddressSpace());

FullExistentialTypeMetadataStructTy = createStructType(*this, "swift.full_existential_type", {
WitnessTablePtrTy,
Expand Down Expand Up @@ -1494,8 +1495,8 @@ llvm::ConstantInt *IRGenModule::getSize(Size size) {
return llvm::ConstantInt::get(SizeTy, size.getValue());
}

llvm::Constant *IRGenModule::getOpaquePtr(llvm::Constant *ptr) {
return llvm::ConstantExpr::getBitCast(ptr, Int8PtrTy);
llvm::Constant *IRGenModule::getOpaquePtrToFn(llvm::Constant *fnptr) {
return llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(fnptr, Int8PtrTy);
}

static void appendEncodedName(raw_ostream &os, StringRef name) {
Expand Down
7 changes: 5 additions & 2 deletions lib/IRGen/IRGenModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -717,9 +717,12 @@ class IRGenModule {
llvm::PointerType *Int8PtrTy; /// i8*
llvm::PointerType *WitnessTableTy;
llvm::PointerType *ObjCSELTy;
llvm::PointerType *FunctionPtrTy;
llvm::PointerType *CaptureDescriptorPtrTy;
};
union {
llvm::PointerType *FunctionPtrTy;
llvm::PointerType *Int8ProgramSpacePtrTy; /// i8* in same address space as programs
};
union {
llvm::PointerType *Int8PtrPtrTy; /// i8**
llvm::PointerType *WitnessTablePtrTy;
Expand Down Expand Up @@ -1622,7 +1625,7 @@ private: \
llvm::Constant *getBool(bool condition);

/// Cast the given constant to i8*.
llvm::Constant *getOpaquePtr(llvm::Constant *pointer);
llvm::Constant *getOpaquePtrToFn(llvm::Constant *fnPointer);

llvm::Constant *getAddrOfAsyncFunctionPointer(LinkEntity entity);
llvm::Constant *getAddrOfAsyncFunctionPointer(SILFunction *function);
Expand Down