Skip to content

Switch all of the indirect-call code in IRGen to FunctionPointer. #11255

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
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
2 changes: 1 addition & 1 deletion lib/IRGen/GenCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1335,7 +1335,7 @@ llvm::CallSite CallEmission::emitCallSite() {

llvm::CallInst *IRBuilder::CreateCall(const FunctionPointer &fn,
ArrayRef<llvm::Value*> args) {
llvm::CallInst *call = CreateCall(fn.getPointer(), args);
llvm::CallInst *call = IRBuilderBase::CreateCall(fn.getPointer(), args);
call->setAttributes(fn.getAttributes());
call->setCallingConv(fn.getCallingConv());
return call;
Expand Down
4 changes: 2 additions & 2 deletions lib/IRGen/GenCast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ void irgen::emitMetatypeDowncast(IRGenFunction &IGF,
Explosion &ex) {
// Pick a runtime entry point and target metadata based on what kind of
// representation we're casting.
llvm::Value *castFn;
llvm::Constant *castFn;
llvm::Value *toMetadata;

switch (toMetatype->getRepresentation()) {
Expand Down Expand Up @@ -630,7 +630,7 @@ void irgen::emitScalarExistentialDowncast(IRGenFunction &IGF,

// Pick the cast function based on the cast mode and on whether we're
// casting a Swift metatype or ObjC object.
llvm::Value *castFn;
llvm::Constant *castFn;
switch (mode) {
case CheckedCastMode::Unconditional:
castFn = objcObject
Expand Down
65 changes: 32 additions & 33 deletions lib/IRGen/GenDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -969,7 +969,7 @@ void IRGenerator::emitEagerClassInitialization() {
false /* = isVarArg */);
llvm::InlineAsm *inlineAsm =
llvm::InlineAsm::get(asmFnTy, "", "r", true /* = SideEffects */);
RegisterIGF.Builder.CreateCall(inlineAsm, MetaData);
RegisterIGF.Builder.CreateAsmCall(inlineAsm, MetaData);
}
RegisterIGF.Builder.CreateRetVoid();

Expand Down Expand Up @@ -1535,17 +1535,15 @@ static bool isPointerTo(llvm::Type *ptrTy, llvm::Type *objTy) {
}

/// Get or create an LLVM function with these linkage rules.
llvm::Function *swift::irgen::createFunction(IRGenModule &IGM,
LinkInfo &linkInfo,
llvm::FunctionType *fnType,
llvm::CallingConv::ID cc,
const llvm::AttributeSet &attrs,
llvm::Function *insertBefore) {
llvm::Function *irgen::createFunction(IRGenModule &IGM,
LinkInfo &linkInfo,
const Signature &signature,
llvm::Function *insertBefore) {
auto name = linkInfo.getName();

llvm::Function *existing = IGM.Module.getFunction(name);
if (existing) {
if (isPointerTo(existing->getType(), fnType))
if (isPointerTo(existing->getType(), signature.getType()))
return cast<llvm::Function>(existing);

IGM.error(SourceLoc(),
Expand All @@ -1557,10 +1555,10 @@ llvm::Function *swift::irgen::createFunction(IRGenModule &IGM,
}

llvm::Function *fn =
llvm::Function::Create(fnType, linkInfo.getLinkage(), name);
llvm::Function::Create(signature.getType(), linkInfo.getLinkage(), name);
fn->setVisibility(linkInfo.getVisibility());
fn->setDLLStorageClass(linkInfo.getDLLStorage());
fn->setCallingConv(cc);
fn->setCallingConv(signature.getCallingConv());

if (insertBefore) {
IGM.Module.getFunctionList().insert(insertBefore->getIterator(), fn);
Expand All @@ -1570,8 +1568,10 @@ llvm::Function *swift::irgen::createFunction(IRGenModule &IGM,

auto initialAttrs = IGM.constructInitialAttributes();
// Merge initialAttrs with attrs.
auto updatedAttrs = attrs.addAttributes(IGM.getLLVMContext(),
llvm::AttributeSet::FunctionIndex, initialAttrs);
auto updatedAttrs =
signature.getAttributes().addAttributes(IGM.getLLVMContext(),
llvm::AttributeSet::FunctionIndex,
initialAttrs);
if (!updatedAttrs.isEmpty())
fn->setAttributes(updatedAttrs);

Expand Down Expand Up @@ -1897,21 +1897,19 @@ llvm::Function *IRGenModule::getAddrOfSILFunction(SILFunction *f,
}

Signature signature = getSignature(f->getLoweredFunctionType());
llvm::FunctionType *fnType = signature.getType();
auto cc = signature.getCallingConv();
auto attrs = signature.getAttributes();
auto &attrs = signature.getMutableAttributes();

LinkInfo link = LinkInfo::get(*this, entity, forDefinition);

if (f->getInlineStrategy() == NoInline) {
attrs = attrs.addAttribute(fnType->getContext(),
attrs = attrs.addAttribute(getLLVMContext(),
llvm::AttributeSet::FunctionIndex, llvm::Attribute::NoInline);
}
if (isReadOnlyFunction(f)) {
attrs = attrs.addAttribute(fnType->getContext(),
attrs = attrs.addAttribute(getLLVMContext(),
llvm::AttributeSet::FunctionIndex, llvm::Attribute::ReadOnly);
}
fn = createFunction(*this, link, fnType, cc, attrs, insertBefore);
fn = createFunction(*this, link, signature, insertBefore);

// If we have an order number for this function, set it up as appropriate.
if (hasOrderNumber) {
Expand Down Expand Up @@ -2511,8 +2509,9 @@ IRGenModule::getAddrOfTypeMetadataAccessFunction(CanType type,
}

auto fnType = llvm::FunctionType::get(TypeMetadataPtrTy, false);
Signature signature(fnType, llvm::AttributeSet(), DefaultCC);
LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
entry = createFunction(*this, link, fnType, DefaultCC, llvm::AttributeSet());
entry = createFunction(*this, link, signature);
return entry;
}

Expand All @@ -2536,8 +2535,9 @@ IRGenModule::getAddrOfGenericTypeMetadataAccessFunction(
}

auto fnType = llvm::FunctionType::get(TypeMetadataPtrTy, genericArgs, false);
Signature signature(fnType, llvm::AttributeSet(), DefaultCC);
LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
entry = createFunction(*this, link, fnType, DefaultCC, llvm::AttributeSet());
entry = createFunction(*this, link, signature);
return entry;
}

Expand Down Expand Up @@ -2846,13 +2846,9 @@ llvm::Function *IRGenModule::getAddrOfValueWitness(CanType abstractType,
return entry;
}

// Find the appropriate function type.
llvm::FunctionType *fnType =
cast<llvm::FunctionType>(
cast<llvm::PointerType>(getValueWitnessTy(index))
->getElementType());
auto signature = getValueWitnessSignature(index);
LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
entry = createFunction(*this, link, fnType, DefaultCC, llvm::AttributeSet());
entry = createFunction(*this, link, signature);
return entry;
}

Expand Down Expand Up @@ -3326,8 +3322,9 @@ IRGenModule::getAddrOfGenericWitnessTableInstantiationFunction(
TypeMetadataPtrTy,
Int8PtrPtrTy },
/*varargs*/ false);
Signature signature(fnType, llvm::AttributeSet(), DefaultCC);
LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
entry = createFunction(*this, link, fnType, DefaultCC, llvm::AttributeSet());
entry = createFunction(*this, link, signature);
return entry;
}

Expand Down Expand Up @@ -3374,8 +3371,9 @@ IRGenModule::getAddrOfWitnessTableAccessFunction(
fnType = llvm::FunctionType::get(WitnessTablePtrTy, false);
}

Signature signature(fnType, llvm::AttributeSet(), DefaultCC);
LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
entry = createFunction(*this, link, fnType, DefaultCC, llvm::AttributeSet());
entry = createFunction(*this, link, signature);
return entry;
}

Expand All @@ -3396,8 +3394,9 @@ IRGenModule::getAddrOfWitnessTableLazyAccessFunction(
llvm::FunctionType *fnType
= llvm::FunctionType::get(WitnessTablePtrTy, false);

Signature signature(fnType, llvm::AttributeSet(), DefaultCC);
LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
entry = createFunction(*this, link, fnType, DefaultCC, llvm::AttributeSet());
entry = createFunction(*this, link, signature);
return entry;
}

Expand Down Expand Up @@ -3446,9 +3445,9 @@ IRGenModule::getAddrOfAssociatedTypeMetadataAccessFunction(
return entry;
}

auto fnType = getAssociatedTypeMetadataAccessFunctionTy();
auto signature = getAssociatedTypeMetadataAccessFunctionSignature();
LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
entry = createFunction(*this, link, fnType, DefaultCC, llvm::AttributeSet());
entry = createFunction(*this, link, signature);
return entry;
}

Expand All @@ -3469,9 +3468,9 @@ IRGenModule::getAddrOfAssociatedTypeWitnessTableAccessFunction(
return entry;
}

auto fnType = getAssociatedTypeWitnessTableAccessFunctionTy();
auto signature = getAssociatedTypeWitnessTableAccessFunctionSignature();
LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
entry = createFunction(*this, link, fnType, DefaultCC, llvm::AttributeSet());
entry = createFunction(*this, link, signature);
return entry;
}

Expand Down
5 changes: 2 additions & 3 deletions lib/IRGen/GenDecl.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,11 @@ namespace swift {
namespace irgen {
class IRGenModule;
class LinkInfo;
class Signature;

llvm::Function *createFunction(IRGenModule &IGM,
LinkInfo &linkInfo,
llvm::FunctionType *fnType,
llvm::CallingConv::ID cc,
const llvm::AttributeSet &attrs,
const Signature &signature,
llvm::Function *insertBefore = nullptr);


Expand Down
38 changes: 17 additions & 21 deletions lib/IRGen/GenFunc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1174,23 +1174,30 @@ static llvm::Function *emitPartialApplicationForwarder(IRGenModule &IGM,
}
}

// Derive the callee function pointer. If we found a function
// pointer statically, great.
// Derive the callee function pointer.
auto fnTy = origSig.getType()->getPointerTo();
llvm::Value *fnPtr;
if (staticFnPtr) {
assert(staticFnPtr->getType() == fnTy && "static function type mismatch?!");
fnPtr = staticFnPtr;
FunctionPointer fnPtr = [&] {
// If we found a function pointer statically, great.
if (staticFnPtr) {
assert(staticFnPtr->getType() == fnTy &&
"static function type mismatch?!");
Signature sig(cast<llvm::FunctionType>(fnTy->getElementType()),
staticFnPtr->getAttributes(),
staticFnPtr->getCallingConv());
return FunctionPointer::forDirect(staticFnPtr, sig);
}

// Otherwise, it was the last thing we added to the layout.

// Otherwise, it was the last thing we added to the layout.
} else {
// The dynamic function pointer is packed "last" into the context,
// and we pulled it out as an argument. Just pop it off.
fnPtr = args.takeLast();
auto fnPtr = args.takeLast();

// It comes out of the context as an i8*. Cast to the function type.
fnPtr = subIGF.Builder.CreateBitCast(fnPtr, fnTy);
}

return FunctionPointer(fnPtr, origSig);
}();

// Derive the context argument if needed. This is either:
// - the saved context argument, in which case it was the last
Expand Down Expand Up @@ -1246,17 +1253,6 @@ static llvm::Function *emitPartialApplicationForwarder(IRGenModule &IGM,

llvm::CallInst *call = subIGF.Builder.CreateCall(fnPtr, args.claimAll());

if (staticFnPtr) {
// Use the attributes and calling convention from the static definition if
// we have it.
call->setAttributes(staticFnPtr->getAttributes());
call->setCallingConv(staticFnPtr->getCallingConv());
} else {
// Otherwise, use the default attributes for the dynamic type.
call->setAttributes(origSig.getAttributes());
// Use the calling convention of the partially applied function type.
call->setCallingConv(origSig.getCallingConv());
}
if (addressesToDeallocate.empty() && !needsAllocas &&
(!consumesContext || !dependsOnContextLifetime))
call->setTailCall();
Expand Down
9 changes: 5 additions & 4 deletions lib/IRGen/GenKeyPath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
//
//===----------------------------------------------------------------------===//

#include "Callee.h"
#include "ConstantBuilder.h"
#include "Explosion.h"
#include "GenClass.h"
Expand Down Expand Up @@ -72,7 +73,7 @@ getAccessorForComputedComponent(IRGenModule &IGM,
if (requirements.empty()) {
return accessorFn;
}

auto accessorFnTy = accessorFn->getType()->getPointerElementType();

// Otherwise, we need a thunk to unmarshal the generic environment from the
Expand Down Expand Up @@ -142,9 +143,9 @@ getAccessorForComputedComponent(IRGenModule &IGM,
forwardingSubs,
&witnessMetadata,
forwardedArgs);
auto call = IGF.Builder.CreateCall(accessorFn, forwardedArgs.claimAll());
if (whichAccessor == Getter)
call->addAttribute(1, llvm::Attribute::StructRet);
auto fnPtr = FunctionPointer::forDirect(IGM, accessorFn,
accessor->getLoweredFunctionType());
IGF.Builder.CreateCall(fnPtr, forwardedArgs.claimAll());

IGF.Builder.CreateRetVoid();
}
Expand Down
10 changes: 6 additions & 4 deletions lib/IRGen/GenMeta.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Module.h"

#include "Address.h"
Expand Down Expand Up @@ -1790,8 +1789,7 @@ namespace {

/// Emit the type layout by projecting it from dynamic type metadata.
llvm::Value *emitFromTypeMetadata(CanType t) {
auto *vwtable = IGF.emitValueWitnessTableRefForLayout(
IGF.IGM.getLoweredType(t));
auto *vwtable = IGF.emitValueWitnessTableRef(IGF.IGM.getLoweredType(t));
return emitFromValueWitnessTablePointer(vwtable);
}

Expand Down Expand Up @@ -4129,14 +4127,18 @@ IRGenFunction::emitValueWitnessTableRefForMetadata(llvm::Value *metadata) {
/// Given a lowered SIL type, load a value witness table that represents its
/// layout.
llvm::Value *
IRGenFunction::emitValueWitnessTableRefForLayout(SILType type) {
IRGenFunction::emitValueWitnessTableRef(SILType type,
llvm::Value **metadataSlot) {
// See if we have a cached projection we can use.
if (auto cached = tryGetLocalTypeDataForLayout(type,
LocalTypeDataKind::forValueWitnessTable())) {
if (metadataSlot)
*metadataSlot = emitTypeMetadataRefForLayout(type);
return cached;
}

auto metadata = emitTypeMetadataRefForLayout(type);
if (metadataSlot) *metadataSlot = metadata;
auto vwtable = emitValueWitnessTableRefForMetadata(metadata);
setScopedLocalTypeDataForLayout(type,
LocalTypeDataKind::forValueWitnessTable(),
Expand Down
4 changes: 2 additions & 2 deletions lib/IRGen/GenObjC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ llvm::Value *IRGenFunction::emitObjCAutoreleaseCall(llvm::Value *val) {
return call;
}

llvm::Value *IRGenModule::getObjCRetainAutoreleasedReturnValueMarker() {
llvm::InlineAsm *IRGenModule::getObjCRetainAutoreleasedReturnValueMarker() {
// Check to see if we've already computed the market. Note that we
// might have cached a null marker, and that's fine.
auto &cache = ObjCRetainAutoreleasedReturnValueMarker;
Expand Down Expand Up @@ -170,7 +170,7 @@ llvm::Value *irgen::emitObjCRetainAutoreleasedReturnValue(IRGenFunction &IGF,
llvm::Value *value) {
// Call the inline-assembly marker if we need one.
if (auto marker = IGF.IGM.getObjCRetainAutoreleasedReturnValueMarker()) {
IGF.Builder.CreateCall(marker, {});
IGF.Builder.CreateAsmCall(marker, {});
}

auto fn = IGF.IGM.getObjCRetainAutoreleasedReturnValueFn();
Expand Down
Loading