Skip to content

Commit 3905955

Browse files
Merge pull request #61232 from aschwaighofer/wip_opaque_ptr_2
IRGen: Pass the elementType of pointers through to operations
2 parents af99c52 + 5a46517 commit 3905955

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+2079
-1958
lines changed

include/swift/Runtime/RuntimeFnWrappersGen.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,5 +46,9 @@ llvm::Constant *getRuntimeFn(llvm::Module &Module, llvm::Constant *&cache,
4646
llvm::ArrayRef<llvm::Attribute::AttrKind> attrs,
4747
irgen::IRGenModule *IGM = nullptr);
4848

49+
llvm::FunctionType *getRuntimeFnType(llvm::Module &Module,
50+
llvm::ArrayRef<llvm::Type *> retTypes,
51+
llvm::ArrayRef<llvm::Type *> argTypes);
52+
4953
} // namespace swift
5054
#endif

lib/IRGen/Address.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,22 @@ namespace irgen {
3131
/// The address of an object in memory.
3232
class Address {
3333
llvm::Value *Addr;
34+
llvm::Type *ElementType;
3435
Alignment Align;
3536

3637
public:
3738
Address() : Addr(nullptr) {}
38-
Address(llvm::Value *addr, Alignment align) : Addr(addr), Align(align) {
39+
40+
Address(llvm::Value *addr, llvm::Type *elementType, Alignment align)
41+
: Addr(addr), ElementType(elementType), Align(align) {
42+
if (!llvm::cast<llvm::PointerType>(addr->getType())
43+
->isOpaqueOrPointeeTypeMatches(elementType)) {
44+
addr->getType()->dump();
45+
elementType->dump();
46+
}
47+
assert(llvm::cast<llvm::PointerType>(addr->getType())
48+
->isOpaqueOrPointeeTypeMatches(elementType) &&
49+
"Incorrect pointer element type");
3950
assert(addr != nullptr && "building an invalid address");
4051
}
4152

@@ -55,6 +66,8 @@ class Address {
5566
llvm::PointerType *getType() const {
5667
return cast<llvm::PointerType>(Addr->getType());
5768
}
69+
70+
llvm::Type *getElementType() const { return ElementType; }
5871
};
5972

6073
/// An address in memory together with the (possibly null) heap

lib/IRGen/Callee.h

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -314,19 +314,32 @@ namespace irgen {
314314
PointerAuthInfo AuthInfo;
315315

316316
Signature Sig;
317+
// If this is an await function pointer contains the signature of the await
318+
// call (without return values).
319+
llvm::Type *awaitSignature = nullptr;
320+
321+
explicit FunctionPointer(Kind kind, llvm::Value *value,
322+
const Signature &signature)
323+
: FunctionPointer(kind, value, PointerAuthInfo(), signature) {}
324+
325+
explicit FunctionPointer(Kind kind, llvm::Value *value,
326+
PointerAuthInfo authInfo,
327+
const Signature &signature)
328+
: FunctionPointer(kind, value, nullptr, authInfo, signature){};
317329

318-
public:
319330
/// Construct a FunctionPointer for an arbitrary pointer value.
320331
/// We may add more arguments to this; try to use the other
321332
/// constructors/factories if possible.
322333
explicit FunctionPointer(Kind kind, llvm::Value *value,
323334
llvm::Value *secondaryValue,
324335
PointerAuthInfo authInfo,
325-
const Signature &signature)
336+
const Signature &signature,
337+
llvm::Type *awaitSignature = nullptr)
326338
: kind(kind), Value(value), SecondaryValue(secondaryValue),
327-
AuthInfo(authInfo), Sig(signature) {
339+
AuthInfo(authInfo), Sig(signature), awaitSignature(awaitSignature) {
328340
// The function pointer should have function type.
329-
assert(value->getType()->getPointerElementType()->isFunctionTy());
341+
assert(!value->getContext().supportsTypedPointers() ||
342+
value->getType()->getPointerElementType()->isFunctionTy());
330343
// TODO: maybe assert similarity to signature.getType()?
331344
if (authInfo) {
332345
if (kind == Kind::Function) {
@@ -337,15 +350,29 @@ namespace irgen {
337350
}
338351
}
339352

340-
explicit FunctionPointer(Kind kind, llvm::Value *value,
341-
PointerAuthInfo authInfo,
342-
const Signature &signature)
343-
: FunctionPointer(kind, value, nullptr, authInfo, signature){};
353+
public:
354+
FunctionPointer()
355+
: kind(FunctionPointer::Kind::Function), Value(nullptr),
356+
SecondaryValue(nullptr) {}
344357

345-
// Temporary only!
346-
explicit FunctionPointer(Kind kind, llvm::Value *value,
347-
const Signature &signature)
348-
: FunctionPointer(kind, value, PointerAuthInfo(), signature) {}
358+
static FunctionPointer createForAsyncCall(llvm::Value *value,
359+
PointerAuthInfo authInfo,
360+
const Signature &signature,
361+
llvm::Type *awaitCallSignature) {
362+
return FunctionPointer(FunctionPointer::Kind::Function, value, nullptr,
363+
authInfo, signature, awaitCallSignature);
364+
}
365+
366+
static FunctionPointer createSigned(Kind kind, llvm::Value *value,
367+
PointerAuthInfo authInfo,
368+
const Signature &signature) {
369+
return FunctionPointer(kind, value, authInfo, signature);
370+
}
371+
372+
static FunctionPointer createUnsigned(Kind kind, llvm::Value *value,
373+
const Signature &signature) {
374+
return FunctionPointer(kind, value, signature);
375+
}
349376

350377
static FunctionPointer forDirect(IRGenModule &IGM, llvm::Constant *value,
351378
llvm::Constant *secondaryValue,
@@ -394,10 +421,7 @@ namespace irgen {
394421
return cast<llvm::Constant>(Value);
395422
}
396423

397-
llvm::FunctionType *getFunctionType() const {
398-
return cast<llvm::FunctionType>(
399-
Value->getType()->getPointerElementType());
400-
}
424+
llvm::FunctionType *getFunctionType() const;
401425

402426
const PointerAuthInfo &getAuthInfo() const {
403427
return AuthInfo;

lib/IRGen/ClassTypeInfo.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ namespace irgen {
2828
/// Layout information for class types.
2929
class ClassTypeInfo : public HeapTypeInfo<ClassTypeInfo> {
3030
ClassDecl *TheClass;
31+
mutable llvm::StructType *classLayoutType;
3132

3233
// The resilient layout of the class, without making any assumptions
3334
// that violate resilience boundaries. This is used to allocate
@@ -47,14 +48,17 @@ class ClassTypeInfo : public HeapTypeInfo<ClassTypeInfo> {
4748
public:
4849
ClassTypeInfo(llvm::PointerType *irType, Size size, SpareBitVector spareBits,
4950
Alignment align, ClassDecl *theClass,
50-
ReferenceCounting refcount)
51+
ReferenceCounting refcount, llvm::StructType *classLayoutType)
5152
: HeapTypeInfo(irType, size, std::move(spareBits), align),
52-
TheClass(theClass), Refcount(refcount) {}
53+
TheClass(theClass), classLayoutType(classLayoutType),
54+
Refcount(refcount) {}
5355

5456
ReferenceCounting getReferenceCounting() const { return Refcount; }
5557

5658
ClassDecl *getClass() const { return TheClass; }
5759

60+
llvm::Type *getClassLayoutType() const { return classLayoutType; }
61+
5862
const ClassLayout &getClassLayout(IRGenModule &IGM, SILType type,
5963
bool forBackwardDeployment) const;
6064

lib/IRGen/EnumPayload.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,8 @@ EnumPayload EnumPayload::load(IRGenFunction &IGF, Address address,
227227
return result;
228228

229229
auto storageTy = getPayloadStorageType(IGF.IGM, result);
230-
address = IGF.Builder.CreateBitCast(address, storageTy->getPointerTo());
231-
230+
address = IGF.Builder.CreateElementBitCast(address, storageTy);
231+
232232
if (result.PayloadValues.size() == 1) {
233233
result.PayloadValues.front() = IGF.Builder.CreateLoad(address);
234234
} else {
@@ -250,8 +250,8 @@ void EnumPayload::store(IRGenFunction &IGF, Address address) const {
250250
return;
251251

252252
auto storageTy = getPayloadStorageType(IGF.IGM, *this);
253-
address = IGF.Builder.CreateBitCast(address, storageTy->getPointerTo());
254-
253+
address = IGF.Builder.CreateElementBitCast(address, storageTy);
254+
255255
if (PayloadValues.size() == 1) {
256256
IGF.Builder.CreateStore(forcePayloadValue(PayloadValues.front()), address);
257257
return;

lib/IRGen/ExtraInhabitants.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,8 @@ llvm::Value *PointerInfo::getExtraInhabitantIndex(IRGenFunction &IGF,
106106
llvm::BasicBlock *contBB = IGF.createBasicBlock("is-valid-pointer");
107107
SmallVector<std::pair<llvm::BasicBlock*, llvm::Value*>, 3> phiValues;
108108
auto invalidIndex = llvm::ConstantInt::getSigned(IGF.IGM.Int32Ty, -1);
109-
110-
src = IGF.Builder.CreateBitCast(src, IGF.IGM.SizeTy->getPointerTo());
109+
110+
src = IGF.Builder.CreateElementBitCast(src, IGF.IGM.SizeTy);
111111

112112
// Check if the inhabitant is below the least valid pointer value.
113113
llvm::Value *val = IGF.Builder.CreateLoad(src);
@@ -206,7 +206,7 @@ void PointerInfo::storeExtraInhabitant(IRGenFunction &IGF,
206206
llvm::ConstantInt::get(IGF.IGM.SizeTy, NumReservedLowBits));
207207
}
208208

209-
dest = IGF.Builder.CreateBitCast(dest, IGF.IGM.SizeTy->getPointerTo());
209+
dest = IGF.Builder.CreateElementBitCast(dest, IGF.IGM.SizeTy);
210210
IGF.Builder.CreateStore(index, dest);
211211
}
212212

lib/IRGen/GenArchetype.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ const TypeInfo *TypeConverter::convertArchetypeType(ArchetypeType *archetype) {
342342
}
343343

344344
// Otherwise, for now, always use an opaque indirect type.
345-
llvm::Type *storageType = IGM.OpaquePtrTy->getPointerElementType();
345+
llvm::Type *storageType = IGM.OpaqueTy;
346346

347347
// Opaque result types can be private and from a different module. In this
348348
// case we can't access their type metadata from another module.
@@ -410,9 +410,9 @@ llvm::Value *irgen::emitDynamicTypeOfOpaqueArchetype(IRGenFunction &IGF,
410410
llvm::Value *metadata =
411411
emitArchetypeTypeMetadataRef(IGF, archetype, MetadataState::Complete)
412412
.getMetadata();
413-
return IGF.Builder.CreateCall(IGF.IGM.getGetDynamicTypeFn(),
414-
{addr.getAddress(), metadata,
415-
llvm::ConstantInt::get(IGF.IGM.Int1Ty, 0)});
413+
return IGF.Builder.CreateCall(
414+
IGF.IGM.getGetDynamicTypeFunctionPointer(),
415+
{addr.getAddress(), metadata, llvm::ConstantInt::get(IGF.IGM.Int1Ty, 0)});
416416
}
417417

418418
static void
@@ -505,7 +505,7 @@ getAddressOfOpaqueTypeDescriptor(IRGenFunction &IGF,
505505
MetadataResponse irgen::emitOpaqueTypeMetadataRef(IRGenFunction &IGF,
506506
CanOpaqueTypeArchetypeType archetype,
507507
DynamicMetadataRequest request) {
508-
auto accessorFn = IGF.IGM.getGetOpaqueTypeMetadataFn();
508+
auto accessorFn = IGF.IGM.getGetOpaqueTypeMetadataFunctionPointer();
509509
auto opaqueDecl = archetype->getDecl();
510510
auto genericParam = archetype->getInterfaceType()
511511
->castTo<GenericTypeParamType>();
@@ -532,7 +532,7 @@ MetadataResponse irgen::emitOpaqueTypeMetadataRef(IRGenFunction &IGF,
532532
llvm::Value *irgen::emitOpaqueTypeWitnessTableRef(IRGenFunction &IGF,
533533
CanOpaqueTypeArchetypeType archetype,
534534
ProtocolDecl *protocol) {
535-
auto accessorFn = IGF.IGM.getGetOpaqueTypeConformanceFn();
535+
auto accessorFn = IGF.IGM.getGetOpaqueTypeConformanceFunctionPointer();
536536
auto opaqueDecl = archetype->getDecl();
537537
assert(archetype->isRoot() && "Can only follow from the root");
538538

0 commit comments

Comments
 (0)