Skip to content

Commit 03d94b4

Browse files
committed
Add default IR attributes to helper functions and convert
several more places to use getOrCreateHelperFunction. This means that several of these places are now emitting shared functions rather than private ones, which I've verified is okay. There are some other places where privacy is still unfortunately necessary. I've also fixed the name of the store-extra-inhabitants helper function to say "store" instead of "get", which is longstanding (but harmless because it's private). Fixes rdar://66707994.
1 parent 63da97d commit 03d94b4

File tree

11 files changed

+437
-292
lines changed

11 files changed

+437
-292
lines changed

lib/IRGen/GenCast.cpp

Lines changed: 67 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ llvm::Value *irgen::emitReferenceToObjCProtocol(IRGenFunction &IGF,
357357
/// The function's output type is (value, witnessTable...)
358358
///
359359
/// The value is NULL if the cast failed.
360-
static llvm::Function *
360+
static llvm::Constant *
361361
emitExistentialScalarCastFn(IRGenModule &IGM,
362362
unsigned numProtocols,
363363
CheckedCastMode mode,
@@ -385,13 +385,7 @@ emitExistentialScalarCastFn(IRGenModule &IGM,
385385
}
386386
}
387387

388-
// See if we already defined this function.
389-
390-
if (auto fn = IGM.Module.getFunction(name))
391-
return fn;
392-
393388
// Build the function type.
394-
395389
llvm::SmallVector<llvm::Type *, 4> argTys;
396390
llvm::SmallVector<llvm::Type *, 4> returnTys;
397391
argTys.push_back(IGM.Int8PtrTy);
@@ -405,84 +399,77 @@ emitExistentialScalarCastFn(IRGenModule &IGM,
405399
}
406400

407401
llvm::Type *returnTy = llvm::StructType::get(IGM.getLLVMContext(), returnTys);
408-
409-
auto fnTy = llvm::FunctionType::get(returnTy, argTys, /*vararg*/ false);
410-
auto fn = llvm::Function::Create(fnTy, llvm::GlobalValue::PrivateLinkage,
411-
llvm::Twine(name), IGM.getModule());
412-
fn->setAttributes(IGM.constructInitialAttributes());
413-
414-
IRGenFunction IGF(IGM, fn);
415-
if (IGM.DebugInfo)
416-
IGM.DebugInfo->emitArtificialFunction(IGF, fn);
417-
Explosion args = IGF.collectParameters();
418-
419-
auto value = args.claimNext();
420-
auto ref = args.claimNext();
421-
auto failBB = IGF.createBasicBlock("fail");
422-
auto conformsToProtocol = IGM.getConformsToProtocolFn();
423-
424-
Explosion rets;
425-
rets.add(value);
426-
427-
// Check the class constraint if necessary.
428-
if (checkSuperclassConstraint) {
429-
auto superclassMetadata = args.claimNext();
430-
auto castFn = IGF.IGM.getDynamicCastMetatypeFn();
431-
auto castResult = IGF.Builder.CreateCall(castFn, {ref,
432-
superclassMetadata});
433-
434-
auto cc = cast<llvm::Function>(castFn)->getCallingConv();
435-
436-
// FIXME: Eventually, we may want to throw.
437-
castResult->setCallingConv(cc);
438-
castResult->setDoesNotThrow();
439402

440-
auto isClass = IGF.Builder.CreateICmpNE(
441-
castResult,
442-
llvm::ConstantPointerNull::get(IGF.IGM.TypeMetadataPtrTy));
403+
return IGM.getOrCreateHelperFunction(name, returnTy, argTys,
404+
[&](IRGenFunction &IGF) {
405+
Explosion args = IGF.collectParameters();
406+
407+
auto value = args.claimNext();
408+
auto ref = args.claimNext();
409+
auto failBB = IGF.createBasicBlock("fail");
410+
auto conformsToProtocol = IGM.getConformsToProtocolFn();
411+
412+
Explosion rets;
413+
rets.add(value);
414+
415+
// Check the class constraint if necessary.
416+
if (checkSuperclassConstraint) {
417+
auto superclassMetadata = args.claimNext();
418+
auto castFn = IGF.IGM.getDynamicCastMetatypeFn();
419+
auto castResult = IGF.Builder.CreateCall(castFn, {ref,
420+
superclassMetadata});
421+
422+
auto cc = cast<llvm::Function>(castFn)->getCallingConv();
423+
424+
// FIXME: Eventually, we may want to throw.
425+
castResult->setCallingConv(cc);
426+
castResult->setDoesNotThrow();
427+
428+
auto isClass = IGF.Builder.CreateICmpNE(
429+
castResult,
430+
llvm::ConstantPointerNull::get(IGF.IGM.TypeMetadataPtrTy));
431+
432+
auto contBB = IGF.createBasicBlock("cont");
433+
IGF.Builder.CreateCondBr(isClass, contBB, failBB);
434+
IGF.Builder.emitBlock(contBB);
435+
} else if (checkClassConstraint) {
436+
auto isClass = IGF.Builder.CreateCall(IGM.getIsClassTypeFn(), ref);
437+
auto contBB = IGF.createBasicBlock("cont");
438+
IGF.Builder.CreateCondBr(isClass, contBB, failBB);
439+
IGF.Builder.emitBlock(contBB);
440+
}
443441

444-
auto contBB = IGF.createBasicBlock("cont");
445-
IGF.Builder.CreateCondBr(isClass, contBB, failBB);
446-
IGF.Builder.emitBlock(contBB);
447-
} else if (checkClassConstraint) {
448-
auto isClass = IGF.Builder.CreateCall(IGM.getIsClassTypeFn(), ref);
449-
auto contBB = IGF.createBasicBlock("cont");
450-
IGF.Builder.CreateCondBr(isClass, contBB, failBB);
451-
IGF.Builder.emitBlock(contBB);
452-
}
442+
// Look up each protocol conformance we want.
443+
for (unsigned i = 0; i < numProtocols; ++i) {
444+
auto proto = args.claimNext();
445+
auto witness = IGF.Builder.CreateCall(conformsToProtocol, {ref, proto});
446+
auto isNull = IGF.Builder.CreateICmpEQ(witness,
447+
llvm::ConstantPointerNull::get(IGM.WitnessTablePtrTy));
448+
auto contBB = IGF.createBasicBlock("cont");
449+
IGF.Builder.CreateCondBr(isNull, failBB, contBB);
450+
451+
IGF.Builder.emitBlock(contBB);
452+
rets.add(witness);
453+
}
453454

454-
// Look up each protocol conformance we want.
455-
for (unsigned i = 0; i < numProtocols; ++i) {
456-
auto proto = args.claimNext();
457-
auto witness = IGF.Builder.CreateCall(conformsToProtocol, {ref, proto});
458-
auto isNull = IGF.Builder.CreateICmpEQ(witness,
459-
llvm::ConstantPointerNull::get(IGM.WitnessTablePtrTy));
460-
auto contBB = IGF.createBasicBlock("cont");
461-
IGF.Builder.CreateCondBr(isNull, failBB, contBB);
455+
// If we succeeded, return the witnesses.
456+
IGF.emitScalarReturn(returnTy, rets);
462457

463-
IGF.Builder.emitBlock(contBB);
464-
rets.add(witness);
465-
}
466-
467-
// If we succeeded, return the witnesses.
468-
IGF.emitScalarReturn(returnTy, rets);
469-
470-
// If we failed, return nil or trap.
471-
IGF.Builder.emitBlock(failBB);
472-
switch (mode) {
473-
case CheckedCastMode::Conditional: {
474-
auto null = llvm::ConstantStruct::getNullValue(returnTy);
475-
IGF.Builder.CreateRet(null);
476-
break;
477-
}
458+
// If we failed, return nil or trap.
459+
IGF.Builder.emitBlock(failBB);
460+
switch (mode) {
461+
case CheckedCastMode::Conditional: {
462+
auto null = llvm::ConstantStruct::getNullValue(returnTy);
463+
IGF.Builder.CreateRet(null);
464+
break;
465+
}
478466

479-
case CheckedCastMode::Unconditional: {
480-
IGF.emitTrap("type cast failed", /*EmitUnreachable=*/true);
481-
break;
482-
}
483-
}
484-
485-
return fn;
467+
case CheckedCastMode::Unconditional: {
468+
IGF.emitTrap("type cast failed", /*EmitUnreachable=*/true);
469+
break;
470+
}
471+
}
472+
});
486473
}
487474

488475
llvm::Value *irgen::emitMetatypeToAnyObjectDowncast(IRGenFunction &IGF,

lib/IRGen/GenDecl.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4862,6 +4862,7 @@ static llvm::Function *shouldDefineHelper(IRGenModule &IGM,
48624862
if (!def) return nullptr;
48634863
if (!def->empty()) return nullptr;
48644864

4865+
def->setAttributes(IGM.constructInitialAttributes());
48654866
ApplyIRLinkage(IRLinkage::InternalLinkOnceODR).to(def);
48664867
def->setDoesNotThrow();
48674868
def->setCallingConv(IGM.DefaultCC);

lib/IRGen/GenKeyPath.cpp

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ getLayoutFunctionForComputedComponent(IRGenModule &IGM,
277277

278278
auto layoutFn = llvm::Function::Create(fnTy,
279279
llvm::GlobalValue::PrivateLinkage, "keypath_get_arg_layout", IGM.getModule());
280+
layoutFn->setAttributes(IGM.constructInitialAttributes());
280281

281282
{
282283
IRGenFunction IGF(IGM, layoutFn);
@@ -378,6 +379,7 @@ getWitnessTableForComputedComponent(IRGenModule &IGM,
378379
auto destroyFn = llvm::Function::Create(destroyType,
379380
llvm::GlobalValue::PrivateLinkage, "keypath_destroy", IGM.getModule());
380381
destroy = destroyFn;
382+
destroyFn->setAttributes(IGM.constructInitialAttributes());
381383

382384
IRGenFunction IGF(IGM, destroyFn);
383385
if (IGM.DebugInfo)
@@ -426,6 +428,7 @@ getWitnessTableForComputedComponent(IRGenModule &IGM,
426428
auto copyFn = llvm::Function::Create(copyType,
427429
llvm::GlobalValue::PrivateLinkage, "keypath_copy", IGM.getModule());
428430
copy = copyFn;
431+
copyFn->setAttributes(IGM.constructInitialAttributes());
429432

430433
IRGenFunction IGF(IGM, copyFn);
431434
if (IGM.DebugInfo)
@@ -538,6 +541,7 @@ getInitializerForComputedComponent(IRGenModule &IGM,
538541

539542
auto initFn = llvm::Function::Create(fnTy,
540543
llvm::GlobalValue::PrivateLinkage, "keypath_arg_init", IGM.getModule());
544+
initFn->setAttributes(IGM.constructInitialAttributes());
541545

542546
{
543547
IRGenFunction IGF(IGM, initFn);
@@ -945,23 +949,16 @@ emitKeyPathComponent(IRGenModule &IGM,
945949
// Note that we'd need to do this anyway in JIT mode because we would
946950
// need to unique the selector at runtime anyway.
947951
auto selectorName = IGM.getObjCSelectorName(declRef);
948-
llvm::Type *fnParams[] = {IGM.Int8PtrTy};
949-
auto fnTy = llvm::FunctionType::get(IGM.Int8PtrTy, fnParams, false);
950952
SmallString<32> fnName;
951953
fnName.append("keypath_get_selector_");
952954
fnName.append(selectorName);
953-
auto fn = cast<llvm::Function>(
954-
IGM.Module.getOrInsertFunction(fnName, fnTy).getCallee());
955-
if (fn->empty()) {
956-
fn->setLinkage(llvm::Function::PrivateLinkage);
957-
IRGenFunction subIGF(IGM, fn);
958-
if (IGM.DebugInfo)
959-
IGM.DebugInfo->emitArtificialFunction(subIGF, fn);
960-
955+
auto fn = IGM.getOrCreateHelperFunction(fnName, IGM.Int8PtrTy,
956+
{IGM.Int8PtrTy},
957+
[&selectorName](IRGenFunction &subIGF) {
961958
auto selectorValue = subIGF.emitObjCSelectorRefLoad(selectorName);
962959
subIGF.Builder.CreateRet(selectorValue);
963-
}
964-
960+
});
961+
965962
idValue = fn;
966963
idResolution = KeyPathComponentHeader::FunctionCall;
967964
} else {

lib/IRGen/GenOpaque.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1354,6 +1354,7 @@ irgen::getOrCreateGetExtraInhabitantTagFunction(IRGenModule &IGM,
13541354
auto fn = llvm::Function::Create(fnTy, llvm::Function::PrivateLinkage,
13551355
"__swift_get_extra_inhabitant_index",
13561356
&IGM.Module);
1357+
fn->setAttributes(IGM.constructInitialAttributes());
13571358
fn->setCallingConv(IGM.SwiftCC);
13581359
IRGenFunction IGF(IGM, fn);
13591360
auto parameters = IGF.collectParameters();
@@ -1427,8 +1428,9 @@ irgen::getOrCreateStoreExtraInhabitantTagFunction(IRGenModule &IGM,
14271428

14281429
// TODO: use a meaningful mangled name and internal/shared linkage.
14291430
auto fn = llvm::Function::Create(fnTy, llvm::Function::PrivateLinkage,
1430-
"__swift_get_extra_inhabitant_index",
1431+
"__swift_store_extra_inhabitant_index",
14311432
&IGM.Module);
1433+
fn->setAttributes(IGM.constructInitialAttributes());
14321434
fn->setCallingConv(IGM.SwiftCC);
14331435
IRGenFunction IGF(IGM, fn);
14341436
auto parameters = IGF.collectParameters();

lib/IRGen/IRGenModule.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1407,6 +1407,7 @@ void IRGenModule::emitAutolinkInfo() {
14071407
llvm::Function::Create(llvm::FunctionType::get(VoidTy, false),
14081408
llvm::GlobalValue::ExternalLinkage, buf,
14091409
&Module);
1410+
ForceImportThunk->setAttributes(constructInitialAttributes());
14101411
ApplyIRLinkage(IRLinkage::ExternalExport).to(ForceImportThunk);
14111412
if (Triple.supportsCOMDAT())
14121413
if (auto *GO = cast<llvm::GlobalObject>(ForceImportThunk))

0 commit comments

Comments
 (0)