Skip to content

Commit 9b91803

Browse files
authored
Merge pull request #11255 from rjmccall/signatures-and-function-pointers
2 parents 52259b7 + a0f20f6 commit 9b91803

37 files changed

+468
-458
lines changed

lib/IRGen/GenCall.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1335,7 +1335,7 @@ llvm::CallSite CallEmission::emitCallSite() {
13351335

13361336
llvm::CallInst *IRBuilder::CreateCall(const FunctionPointer &fn,
13371337
ArrayRef<llvm::Value*> args) {
1338-
llvm::CallInst *call = CreateCall(fn.getPointer(), args);
1338+
llvm::CallInst *call = IRBuilderBase::CreateCall(fn.getPointer(), args);
13391339
call->setAttributes(fn.getAttributes());
13401340
call->setCallingConv(fn.getCallingConv());
13411341
return call;

lib/IRGen/GenCast.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ void irgen::emitMetatypeDowncast(IRGenFunction &IGF,
224224
Explosion &ex) {
225225
// Pick a runtime entry point and target metadata based on what kind of
226226
// representation we're casting.
227-
llvm::Value *castFn;
227+
llvm::Constant *castFn;
228228
llvm::Value *toMetadata;
229229

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

631631
// Pick the cast function based on the cast mode and on whether we're
632632
// casting a Swift metatype or ObjC object.
633-
llvm::Value *castFn;
633+
llvm::Constant *castFn;
634634
switch (mode) {
635635
case CheckedCastMode::Unconditional:
636636
castFn = objcObject

lib/IRGen/GenDecl.cpp

Lines changed: 32 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -969,7 +969,7 @@ void IRGenerator::emitEagerClassInitialization() {
969969
false /* = isVarArg */);
970970
llvm::InlineAsm *inlineAsm =
971971
llvm::InlineAsm::get(asmFnTy, "", "r", true /* = SideEffects */);
972-
RegisterIGF.Builder.CreateCall(inlineAsm, MetaData);
972+
RegisterIGF.Builder.CreateAsmCall(inlineAsm, MetaData);
973973
}
974974
RegisterIGF.Builder.CreateRetVoid();
975975

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

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

15461544
llvm::Function *existing = IGM.Module.getFunction(name);
15471545
if (existing) {
1548-
if (isPointerTo(existing->getType(), fnType))
1546+
if (isPointerTo(existing->getType(), signature.getType()))
15491547
return cast<llvm::Function>(existing);
15501548

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

15591557
llvm::Function *fn =
1560-
llvm::Function::Create(fnType, linkInfo.getLinkage(), name);
1558+
llvm::Function::Create(signature.getType(), linkInfo.getLinkage(), name);
15611559
fn->setVisibility(linkInfo.getVisibility());
15621560
fn->setDLLStorageClass(linkInfo.getDLLStorage());
1563-
fn->setCallingConv(cc);
1561+
fn->setCallingConv(signature.getCallingConv());
15641562

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

15711569
auto initialAttrs = IGM.constructInitialAttributes();
15721570
// Merge initialAttrs with attrs.
1573-
auto updatedAttrs = attrs.addAttributes(IGM.getLLVMContext(),
1574-
llvm::AttributeSet::FunctionIndex, initialAttrs);
1571+
auto updatedAttrs =
1572+
signature.getAttributes().addAttributes(IGM.getLLVMContext(),
1573+
llvm::AttributeSet::FunctionIndex,
1574+
initialAttrs);
15751575
if (!updatedAttrs.isEmpty())
15761576
fn->setAttributes(updatedAttrs);
15771577

@@ -1897,21 +1897,19 @@ llvm::Function *IRGenModule::getAddrOfSILFunction(SILFunction *f,
18971897
}
18981898

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

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

19061904
if (f->getInlineStrategy() == NoInline) {
1907-
attrs = attrs.addAttribute(fnType->getContext(),
1905+
attrs = attrs.addAttribute(getLLVMContext(),
19081906
llvm::AttributeSet::FunctionIndex, llvm::Attribute::NoInline);
19091907
}
19101908
if (isReadOnlyFunction(f)) {
1911-
attrs = attrs.addAttribute(fnType->getContext(),
1909+
attrs = attrs.addAttribute(getLLVMContext(),
19121910
llvm::AttributeSet::FunctionIndex, llvm::Attribute::ReadOnly);
19131911
}
1914-
fn = createFunction(*this, link, fnType, cc, attrs, insertBefore);
1912+
fn = createFunction(*this, link, signature, insertBefore);
19151913

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

25132511
auto fnType = llvm::FunctionType::get(TypeMetadataPtrTy, false);
2512+
Signature signature(fnType, llvm::AttributeSet(), DefaultCC);
25142513
LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
2515-
entry = createFunction(*this, link, fnType, DefaultCC, llvm::AttributeSet());
2514+
entry = createFunction(*this, link, signature);
25162515
return entry;
25172516
}
25182517

@@ -2536,8 +2535,9 @@ IRGenModule::getAddrOfGenericTypeMetadataAccessFunction(
25362535
}
25372536

25382537
auto fnType = llvm::FunctionType::get(TypeMetadataPtrTy, genericArgs, false);
2538+
Signature signature(fnType, llvm::AttributeSet(), DefaultCC);
25392539
LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
2540-
entry = createFunction(*this, link, fnType, DefaultCC, llvm::AttributeSet());
2540+
entry = createFunction(*this, link, signature);
25412541
return entry;
25422542
}
25432543

@@ -2846,13 +2846,9 @@ llvm::Function *IRGenModule::getAddrOfValueWitness(CanType abstractType,
28462846
return entry;
28472847
}
28482848

2849-
// Find the appropriate function type.
2850-
llvm::FunctionType *fnType =
2851-
cast<llvm::FunctionType>(
2852-
cast<llvm::PointerType>(getValueWitnessTy(index))
2853-
->getElementType());
2849+
auto signature = getValueWitnessSignature(index);
28542850
LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
2855-
entry = createFunction(*this, link, fnType, DefaultCC, llvm::AttributeSet());
2851+
entry = createFunction(*this, link, signature);
28562852
return entry;
28572853
}
28582854

@@ -3326,8 +3322,9 @@ IRGenModule::getAddrOfGenericWitnessTableInstantiationFunction(
33263322
TypeMetadataPtrTy,
33273323
Int8PtrPtrTy },
33283324
/*varargs*/ false);
3325+
Signature signature(fnType, llvm::AttributeSet(), DefaultCC);
33293326
LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
3330-
entry = createFunction(*this, link, fnType, DefaultCC, llvm::AttributeSet());
3327+
entry = createFunction(*this, link, signature);
33313328
return entry;
33323329
}
33333330

@@ -3374,8 +3371,9 @@ IRGenModule::getAddrOfWitnessTableAccessFunction(
33743371
fnType = llvm::FunctionType::get(WitnessTablePtrTy, false);
33753372
}
33763373

3374+
Signature signature(fnType, llvm::AttributeSet(), DefaultCC);
33773375
LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
3378-
entry = createFunction(*this, link, fnType, DefaultCC, llvm::AttributeSet());
3376+
entry = createFunction(*this, link, signature);
33793377
return entry;
33803378
}
33813379

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

3397+
Signature signature(fnType, llvm::AttributeSet(), DefaultCC);
33993398
LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
3400-
entry = createFunction(*this, link, fnType, DefaultCC, llvm::AttributeSet());
3399+
entry = createFunction(*this, link, signature);
34013400
return entry;
34023401
}
34033402

@@ -3446,9 +3445,9 @@ IRGenModule::getAddrOfAssociatedTypeMetadataAccessFunction(
34463445
return entry;
34473446
}
34483447

3449-
auto fnType = getAssociatedTypeMetadataAccessFunctionTy();
3448+
auto signature = getAssociatedTypeMetadataAccessFunctionSignature();
34503449
LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
3451-
entry = createFunction(*this, link, fnType, DefaultCC, llvm::AttributeSet());
3450+
entry = createFunction(*this, link, signature);
34523451
return entry;
34533452
}
34543453

@@ -3469,9 +3468,9 @@ IRGenModule::getAddrOfAssociatedTypeWitnessTableAccessFunction(
34693468
return entry;
34703469
}
34713470

3472-
auto fnType = getAssociatedTypeWitnessTableAccessFunctionTy();
3471+
auto signature = getAssociatedTypeWitnessTableAccessFunctionSignature();
34733472
LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
3474-
entry = createFunction(*this, link, fnType, DefaultCC, llvm::AttributeSet());
3473+
entry = createFunction(*this, link, signature);
34753474
return entry;
34763475
}
34773476

lib/IRGen/GenDecl.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,11 @@ namespace swift {
3030
namespace irgen {
3131
class IRGenModule;
3232
class LinkInfo;
33+
class Signature;
3334

3435
llvm::Function *createFunction(IRGenModule &IGM,
3536
LinkInfo &linkInfo,
36-
llvm::FunctionType *fnType,
37-
llvm::CallingConv::ID cc,
38-
const llvm::AttributeSet &attrs,
37+
const Signature &signature,
3938
llvm::Function *insertBefore = nullptr);
4039

4140

lib/IRGen/GenFunc.cpp

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1174,23 +1174,30 @@ static llvm::Function *emitPartialApplicationForwarder(IRGenModule &IGM,
11741174
}
11751175
}
11761176

1177-
// Derive the callee function pointer. If we found a function
1178-
// pointer statically, great.
1177+
// Derive the callee function pointer.
11791178
auto fnTy = origSig.getType()->getPointerTo();
1180-
llvm::Value *fnPtr;
1181-
if (staticFnPtr) {
1182-
assert(staticFnPtr->getType() == fnTy && "static function type mismatch?!");
1183-
fnPtr = staticFnPtr;
1179+
FunctionPointer fnPtr = [&] {
1180+
// If we found a function pointer statically, great.
1181+
if (staticFnPtr) {
1182+
assert(staticFnPtr->getType() == fnTy &&
1183+
"static function type mismatch?!");
1184+
Signature sig(cast<llvm::FunctionType>(fnTy->getElementType()),
1185+
staticFnPtr->getAttributes(),
1186+
staticFnPtr->getCallingConv());
1187+
return FunctionPointer::forDirect(staticFnPtr, sig);
1188+
}
1189+
1190+
// Otherwise, it was the last thing we added to the layout.
11841191

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

11911196
// It comes out of the context as an i8*. Cast to the function type.
11921197
fnPtr = subIGF.Builder.CreateBitCast(fnPtr, fnTy);
1193-
}
1198+
1199+
return FunctionPointer(fnPtr, origSig);
1200+
}();
11941201

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

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

1249-
if (staticFnPtr) {
1250-
// Use the attributes and calling convention from the static definition if
1251-
// we have it.
1252-
call->setAttributes(staticFnPtr->getAttributes());
1253-
call->setCallingConv(staticFnPtr->getCallingConv());
1254-
} else {
1255-
// Otherwise, use the default attributes for the dynamic type.
1256-
call->setAttributes(origSig.getAttributes());
1257-
// Use the calling convention of the partially applied function type.
1258-
call->setCallingConv(origSig.getCallingConv());
1259-
}
12601256
if (addressesToDeallocate.empty() && !needsAllocas &&
12611257
(!consumesContext || !dependsOnContextLifetime))
12621258
call->setTailCall();

lib/IRGen/GenKeyPath.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
//
1616
//===----------------------------------------------------------------------===//
1717

18+
#include "Callee.h"
1819
#include "ConstantBuilder.h"
1920
#include "Explosion.h"
2021
#include "GenClass.h"
@@ -72,7 +73,7 @@ getAccessorForComputedComponent(IRGenModule &IGM,
7273
if (requirements.empty()) {
7374
return accessorFn;
7475
}
75-
76+
7677
auto accessorFnTy = accessorFn->getType()->getPointerElementType();
7778

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

149150
IGF.Builder.CreateRetVoid();
150151
}

lib/IRGen/GenMeta.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
#include "llvm/IR/DerivedTypes.h"
3434
#include "llvm/IR/Function.h"
3535
#include "llvm/IR/GlobalVariable.h"
36-
#include "llvm/IR/InlineAsm.h"
3736
#include "llvm/IR/Module.h"
3837

3938
#include "Address.h"
@@ -1790,8 +1789,7 @@ namespace {
17901789

17911790
/// Emit the type layout by projecting it from dynamic type metadata.
17921791
llvm::Value *emitFromTypeMetadata(CanType t) {
1793-
auto *vwtable = IGF.emitValueWitnessTableRefForLayout(
1794-
IGF.IGM.getLoweredType(t));
1792+
auto *vwtable = IGF.emitValueWitnessTableRef(IGF.IGM.getLoweredType(t));
17951793
return emitFromValueWitnessTablePointer(vwtable);
17961794
}
17971795

@@ -4129,14 +4127,18 @@ IRGenFunction::emitValueWitnessTableRefForMetadata(llvm::Value *metadata) {
41294127
/// Given a lowered SIL type, load a value witness table that represents its
41304128
/// layout.
41314129
llvm::Value *
4132-
IRGenFunction::emitValueWitnessTableRefForLayout(SILType type) {
4130+
IRGenFunction::emitValueWitnessTableRef(SILType type,
4131+
llvm::Value **metadataSlot) {
41334132
// See if we have a cached projection we can use.
41344133
if (auto cached = tryGetLocalTypeDataForLayout(type,
41354134
LocalTypeDataKind::forValueWitnessTable())) {
4135+
if (metadataSlot)
4136+
*metadataSlot = emitTypeMetadataRefForLayout(type);
41364137
return cached;
41374138
}
41384139

41394140
auto metadata = emitTypeMetadataRefForLayout(type);
4141+
if (metadataSlot) *metadataSlot = metadata;
41404142
auto vwtable = emitValueWitnessTableRefForMetadata(metadata);
41414143
setScopedLocalTypeDataForLayout(type,
41424144
LocalTypeDataKind::forValueWitnessTable(),

lib/IRGen/GenObjC.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ llvm::Value *IRGenFunction::emitObjCAutoreleaseCall(llvm::Value *val) {
124124
return call;
125125
}
126126

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

176176
auto fn = IGF.IGM.getObjCRetainAutoreleasedReturnValueFn();

0 commit comments

Comments
 (0)