Skip to content

IRGen: Pass the elementType of pointers through to operations #61232

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

Merged
merged 3 commits into from
Oct 4, 2022
Merged
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
4 changes: 4 additions & 0 deletions include/swift/Runtime/RuntimeFnWrappersGen.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,9 @@ llvm::Constant *getRuntimeFn(llvm::Module &Module, llvm::Constant *&cache,
llvm::ArrayRef<llvm::Attribute::AttrKind> attrs,
irgen::IRGenModule *IGM = nullptr);

llvm::FunctionType *getRuntimeFnType(llvm::Module &Module,
llvm::ArrayRef<llvm::Type *> retTypes,
llvm::ArrayRef<llvm::Type *> argTypes);

} // namespace swift
#endif
15 changes: 14 additions & 1 deletion lib/IRGen/Address.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,22 @@ namespace irgen {
/// The address of an object in memory.
class Address {
llvm::Value *Addr;
llvm::Type *ElementType;
Alignment Align;

public:
Address() : Addr(nullptr) {}
Address(llvm::Value *addr, Alignment align) : Addr(addr), Align(align) {

Address(llvm::Value *addr, llvm::Type *elementType, Alignment align)
: Addr(addr), ElementType(elementType), Align(align) {
if (!llvm::cast<llvm::PointerType>(addr->getType())
->isOpaqueOrPointeeTypeMatches(elementType)) {
addr->getType()->dump();
elementType->dump();
}
assert(llvm::cast<llvm::PointerType>(addr->getType())
->isOpaqueOrPointeeTypeMatches(elementType) &&
"Incorrect pointer element type");
assert(addr != nullptr && "building an invalid address");
}

Expand All @@ -55,6 +66,8 @@ class Address {
llvm::PointerType *getType() const {
return cast<llvm::PointerType>(Addr->getType());
}

llvm::Type *getElementType() const { return ElementType; }
};

/// An address in memory together with the (possibly null) heap
Expand Down
56 changes: 40 additions & 16 deletions lib/IRGen/Callee.h
Original file line number Diff line number Diff line change
Expand Up @@ -314,19 +314,32 @@ namespace irgen {
PointerAuthInfo AuthInfo;

Signature Sig;
// If this is an await function pointer contains the signature of the await
// call (without return values).
llvm::Type *awaitSignature = nullptr;

explicit FunctionPointer(Kind kind, llvm::Value *value,
const Signature &signature)
: FunctionPointer(kind, value, PointerAuthInfo(), signature) {}

explicit FunctionPointer(Kind kind, llvm::Value *value,
PointerAuthInfo authInfo,
const Signature &signature)
: FunctionPointer(kind, value, nullptr, authInfo, signature){};

public:
/// Construct a FunctionPointer for an arbitrary pointer value.
/// We may add more arguments to this; try to use the other
/// constructors/factories if possible.
explicit FunctionPointer(Kind kind, llvm::Value *value,
llvm::Value *secondaryValue,
PointerAuthInfo authInfo,
const Signature &signature)
const Signature &signature,
llvm::Type *awaitSignature = nullptr)
: kind(kind), Value(value), SecondaryValue(secondaryValue),
AuthInfo(authInfo), Sig(signature) {
AuthInfo(authInfo), Sig(signature), awaitSignature(awaitSignature) {
// The function pointer should have function type.
assert(value->getType()->getPointerElementType()->isFunctionTy());
assert(!value->getContext().supportsTypedPointers() ||
value->getType()->getPointerElementType()->isFunctionTy());
// TODO: maybe assert similarity to signature.getType()?
if (authInfo) {
if (kind == Kind::Function) {
Expand All @@ -337,15 +350,29 @@ namespace irgen {
}
}

explicit FunctionPointer(Kind kind, llvm::Value *value,
PointerAuthInfo authInfo,
const Signature &signature)
: FunctionPointer(kind, value, nullptr, authInfo, signature){};
public:
FunctionPointer()
: kind(FunctionPointer::Kind::Function), Value(nullptr),
SecondaryValue(nullptr) {}

// Temporary only!
explicit FunctionPointer(Kind kind, llvm::Value *value,
const Signature &signature)
: FunctionPointer(kind, value, PointerAuthInfo(), signature) {}
static FunctionPointer createForAsyncCall(llvm::Value *value,
PointerAuthInfo authInfo,
const Signature &signature,
llvm::Type *awaitCallSignature) {
return FunctionPointer(FunctionPointer::Kind::Function, value, nullptr,
authInfo, signature, awaitCallSignature);
}

static FunctionPointer createSigned(Kind kind, llvm::Value *value,
PointerAuthInfo authInfo,
const Signature &signature) {
return FunctionPointer(kind, value, authInfo, signature);
}

static FunctionPointer createUnsigned(Kind kind, llvm::Value *value,
const Signature &signature) {
return FunctionPointer(kind, value, signature);
}

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

llvm::FunctionType *getFunctionType() const {
return cast<llvm::FunctionType>(
Value->getType()->getPointerElementType());
}
llvm::FunctionType *getFunctionType() const;

const PointerAuthInfo &getAuthInfo() const {
return AuthInfo;
Expand Down
8 changes: 6 additions & 2 deletions lib/IRGen/ClassTypeInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ namespace irgen {
/// Layout information for class types.
class ClassTypeInfo : public HeapTypeInfo<ClassTypeInfo> {
ClassDecl *TheClass;
mutable llvm::StructType *classLayoutType;

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

ReferenceCounting getReferenceCounting() const { return Refcount; }

ClassDecl *getClass() const { return TheClass; }

llvm::Type *getClassLayoutType() const { return classLayoutType; }

const ClassLayout &getClassLayout(IRGenModule &IGM, SILType type,
bool forBackwardDeployment) const;

Expand Down
8 changes: 4 additions & 4 deletions lib/IRGen/EnumPayload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,8 +227,8 @@ EnumPayload EnumPayload::load(IRGenFunction &IGF, Address address,
return result;

auto storageTy = getPayloadStorageType(IGF.IGM, result);
address = IGF.Builder.CreateBitCast(address, storageTy->getPointerTo());
address = IGF.Builder.CreateElementBitCast(address, storageTy);

if (result.PayloadValues.size() == 1) {
result.PayloadValues.front() = IGF.Builder.CreateLoad(address);
} else {
Expand All @@ -250,8 +250,8 @@ void EnumPayload::store(IRGenFunction &IGF, Address address) const {
return;

auto storageTy = getPayloadStorageType(IGF.IGM, *this);
address = IGF.Builder.CreateBitCast(address, storageTy->getPointerTo());
address = IGF.Builder.CreateElementBitCast(address, storageTy);

if (PayloadValues.size() == 1) {
IGF.Builder.CreateStore(forcePayloadValue(PayloadValues.front()), address);
return;
Expand Down
6 changes: 3 additions & 3 deletions lib/IRGen/ExtraInhabitants.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@ llvm::Value *PointerInfo::getExtraInhabitantIndex(IRGenFunction &IGF,
llvm::BasicBlock *contBB = IGF.createBasicBlock("is-valid-pointer");
SmallVector<std::pair<llvm::BasicBlock*, llvm::Value*>, 3> phiValues;
auto invalidIndex = llvm::ConstantInt::getSigned(IGF.IGM.Int32Ty, -1);
src = IGF.Builder.CreateBitCast(src, IGF.IGM.SizeTy->getPointerTo());

src = IGF.Builder.CreateElementBitCast(src, IGF.IGM.SizeTy);

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

dest = IGF.Builder.CreateBitCast(dest, IGF.IGM.SizeTy->getPointerTo());
dest = IGF.Builder.CreateElementBitCast(dest, IGF.IGM.SizeTy);
IGF.Builder.CreateStore(index, dest);
}

Expand Down
12 changes: 6 additions & 6 deletions lib/IRGen/GenArchetype.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ const TypeInfo *TypeConverter::convertArchetypeType(ArchetypeType *archetype) {
}

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

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

static void
Expand Down Expand Up @@ -505,7 +505,7 @@ getAddressOfOpaqueTypeDescriptor(IRGenFunction &IGF,
MetadataResponse irgen::emitOpaqueTypeMetadataRef(IRGenFunction &IGF,
CanOpaqueTypeArchetypeType archetype,
DynamicMetadataRequest request) {
auto accessorFn = IGF.IGM.getGetOpaqueTypeMetadataFn();
auto accessorFn = IGF.IGM.getGetOpaqueTypeMetadataFunctionPointer();
auto opaqueDecl = archetype->getDecl();
auto genericParam = archetype->getInterfaceType()
->castTo<GenericTypeParamType>();
Expand All @@ -532,7 +532,7 @@ MetadataResponse irgen::emitOpaqueTypeMetadataRef(IRGenFunction &IGF,
llvm::Value *irgen::emitOpaqueTypeWitnessTableRef(IRGenFunction &IGF,
CanOpaqueTypeArchetypeType archetype,
ProtocolDecl *protocol) {
auto accessorFn = IGF.IGM.getGetOpaqueTypeConformanceFn();
auto accessorFn = IGF.IGM.getGetOpaqueTypeConformanceFunctionPointer();
auto opaqueDecl = archetype->getDecl();
assert(archetype->isRoot() && "Can only follow from the root");

Expand Down
Loading