Skip to content

Commit a0f20f6

Browse files
committed
Switch all of the indirect-call code in IRGen to FunctionPointer.
To make this stick, I've disallowed direct use of that overload of CreateCall. I've left the Constant overloads available, but eventually we might want to consider fixing those, too, just to get all of this code out of the business of manually remembering to pass around attributes and calling conventions. The test changes reflect the fact that we weren't really setting attributes consistently at all, in this case on value witnesses.
1 parent 3c7af4e commit a0f20f6

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)