Skip to content

Add default IR attributes to helper functions #33379

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 1 commit into from
Aug 9, 2020
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
147 changes: 67 additions & 80 deletions lib/IRGen/GenCast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ llvm::Value *irgen::emitReferenceToObjCProtocol(IRGenFunction &IGF,
/// The function's output type is (value, witnessTable...)
///
/// The value is NULL if the cast failed.
static llvm::Function *
static llvm::Constant *
emitExistentialScalarCastFn(IRGenModule &IGM,
unsigned numProtocols,
CheckedCastMode mode,
Expand Down Expand Up @@ -385,13 +385,7 @@ emitExistentialScalarCastFn(IRGenModule &IGM,
}
}

// See if we already defined this function.

if (auto fn = IGM.Module.getFunction(name))
return fn;

// Build the function type.

llvm::SmallVector<llvm::Type *, 4> argTys;
llvm::SmallVector<llvm::Type *, 4> returnTys;
argTys.push_back(IGM.Int8PtrTy);
Expand All @@ -405,84 +399,77 @@ emitExistentialScalarCastFn(IRGenModule &IGM,
}

llvm::Type *returnTy = llvm::StructType::get(IGM.getLLVMContext(), returnTys);

auto fnTy = llvm::FunctionType::get(returnTy, argTys, /*vararg*/ false);
auto fn = llvm::Function::Create(fnTy, llvm::GlobalValue::PrivateLinkage,
llvm::Twine(name), IGM.getModule());
fn->setAttributes(IGM.constructInitialAttributes());

IRGenFunction IGF(IGM, fn);
if (IGM.DebugInfo)
IGM.DebugInfo->emitArtificialFunction(IGF, fn);
Explosion args = IGF.collectParameters();

auto value = args.claimNext();
auto ref = args.claimNext();
auto failBB = IGF.createBasicBlock("fail");
auto conformsToProtocol = IGM.getConformsToProtocolFn();

Explosion rets;
rets.add(value);

// Check the class constraint if necessary.
if (checkSuperclassConstraint) {
auto superclassMetadata = args.claimNext();
auto castFn = IGF.IGM.getDynamicCastMetatypeFn();
auto castResult = IGF.Builder.CreateCall(castFn, {ref,
superclassMetadata});

auto cc = cast<llvm::Function>(castFn)->getCallingConv();

// FIXME: Eventually, we may want to throw.
castResult->setCallingConv(cc);
castResult->setDoesNotThrow();

auto isClass = IGF.Builder.CreateICmpNE(
castResult,
llvm::ConstantPointerNull::get(IGF.IGM.TypeMetadataPtrTy));
return IGM.getOrCreateHelperFunction(name, returnTy, argTys,
[&](IRGenFunction &IGF) {
Explosion args = IGF.collectParameters();

auto value = args.claimNext();
auto ref = args.claimNext();
auto failBB = IGF.createBasicBlock("fail");
auto conformsToProtocol = IGM.getConformsToProtocolFn();

Explosion rets;
rets.add(value);

// Check the class constraint if necessary.
if (checkSuperclassConstraint) {
auto superclassMetadata = args.claimNext();
auto castFn = IGF.IGM.getDynamicCastMetatypeFn();
auto castResult = IGF.Builder.CreateCall(castFn, {ref,
superclassMetadata});

auto cc = cast<llvm::Function>(castFn)->getCallingConv();

// FIXME: Eventually, we may want to throw.
castResult->setCallingConv(cc);
castResult->setDoesNotThrow();

auto isClass = IGF.Builder.CreateICmpNE(
castResult,
llvm::ConstantPointerNull::get(IGF.IGM.TypeMetadataPtrTy));

auto contBB = IGF.createBasicBlock("cont");
IGF.Builder.CreateCondBr(isClass, contBB, failBB);
IGF.Builder.emitBlock(contBB);
} else if (checkClassConstraint) {
auto isClass = IGF.Builder.CreateCall(IGM.getIsClassTypeFn(), ref);
auto contBB = IGF.createBasicBlock("cont");
IGF.Builder.CreateCondBr(isClass, contBB, failBB);
IGF.Builder.emitBlock(contBB);
}

auto contBB = IGF.createBasicBlock("cont");
IGF.Builder.CreateCondBr(isClass, contBB, failBB);
IGF.Builder.emitBlock(contBB);
} else if (checkClassConstraint) {
auto isClass = IGF.Builder.CreateCall(IGM.getIsClassTypeFn(), ref);
auto contBB = IGF.createBasicBlock("cont");
IGF.Builder.CreateCondBr(isClass, contBB, failBB);
IGF.Builder.emitBlock(contBB);
}
// Look up each protocol conformance we want.
for (unsigned i = 0; i < numProtocols; ++i) {
auto proto = args.claimNext();
auto witness = IGF.Builder.CreateCall(conformsToProtocol, {ref, proto});
auto isNull = IGF.Builder.CreateICmpEQ(witness,
llvm::ConstantPointerNull::get(IGM.WitnessTablePtrTy));
auto contBB = IGF.createBasicBlock("cont");
IGF.Builder.CreateCondBr(isNull, failBB, contBB);

IGF.Builder.emitBlock(contBB);
rets.add(witness);
}

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

IGF.Builder.emitBlock(contBB);
rets.add(witness);
}

// If we succeeded, return the witnesses.
IGF.emitScalarReturn(returnTy, rets);

// If we failed, return nil or trap.
IGF.Builder.emitBlock(failBB);
switch (mode) {
case CheckedCastMode::Conditional: {
auto null = llvm::ConstantStruct::getNullValue(returnTy);
IGF.Builder.CreateRet(null);
break;
}
// If we failed, return nil or trap.
IGF.Builder.emitBlock(failBB);
switch (mode) {
case CheckedCastMode::Conditional: {
auto null = llvm::ConstantStruct::getNullValue(returnTy);
IGF.Builder.CreateRet(null);
break;
}

case CheckedCastMode::Unconditional: {
IGF.emitTrap("type cast failed", /*EmitUnreachable=*/true);
break;
}
}

return fn;
case CheckedCastMode::Unconditional: {
IGF.emitTrap("type cast failed", /*EmitUnreachable=*/true);
break;
}
}
});
}

llvm::Value *irgen::emitMetatypeToAnyObjectDowncast(IRGenFunction &IGF,
Expand Down
1 change: 1 addition & 0 deletions lib/IRGen/GenDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4862,6 +4862,7 @@ static llvm::Function *shouldDefineHelper(IRGenModule &IGM,
if (!def) return nullptr;
if (!def->empty()) return nullptr;

def->setAttributes(IGM.constructInitialAttributes());
ApplyIRLinkage(IRLinkage::InternalLinkOnceODR).to(def);
def->setDoesNotThrow();
def->setCallingConv(IGM.DefaultCC);
Expand Down
21 changes: 9 additions & 12 deletions lib/IRGen/GenKeyPath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ getLayoutFunctionForComputedComponent(IRGenModule &IGM,

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

{
IRGenFunction IGF(IGM, layoutFn);
Expand Down Expand Up @@ -378,6 +379,7 @@ getWitnessTableForComputedComponent(IRGenModule &IGM,
auto destroyFn = llvm::Function::Create(destroyType,
llvm::GlobalValue::PrivateLinkage, "keypath_destroy", IGM.getModule());
destroy = destroyFn;
destroyFn->setAttributes(IGM.constructInitialAttributes());

IRGenFunction IGF(IGM, destroyFn);
if (IGM.DebugInfo)
Expand Down Expand Up @@ -426,6 +428,7 @@ getWitnessTableForComputedComponent(IRGenModule &IGM,
auto copyFn = llvm::Function::Create(copyType,
llvm::GlobalValue::PrivateLinkage, "keypath_copy", IGM.getModule());
copy = copyFn;
copyFn->setAttributes(IGM.constructInitialAttributes());

IRGenFunction IGF(IGM, copyFn);
if (IGM.DebugInfo)
Expand Down Expand Up @@ -538,6 +541,7 @@ getInitializerForComputedComponent(IRGenModule &IGM,

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

{
IRGenFunction IGF(IGM, initFn);
Expand Down Expand Up @@ -945,23 +949,16 @@ emitKeyPathComponent(IRGenModule &IGM,
// Note that we'd need to do this anyway in JIT mode because we would
// need to unique the selector at runtime anyway.
auto selectorName = IGM.getObjCSelectorName(declRef);
llvm::Type *fnParams[] = {IGM.Int8PtrTy};
auto fnTy = llvm::FunctionType::get(IGM.Int8PtrTy, fnParams, false);
SmallString<32> fnName;
fnName.append("keypath_get_selector_");
fnName.append(selectorName);
auto fn = cast<llvm::Function>(
IGM.Module.getOrInsertFunction(fnName, fnTy).getCallee());
if (fn->empty()) {
fn->setLinkage(llvm::Function::PrivateLinkage);
IRGenFunction subIGF(IGM, fn);
if (IGM.DebugInfo)
IGM.DebugInfo->emitArtificialFunction(subIGF, fn);

auto fn = IGM.getOrCreateHelperFunction(fnName, IGM.Int8PtrTy,
{IGM.Int8PtrTy},
[&selectorName](IRGenFunction &subIGF) {
auto selectorValue = subIGF.emitObjCSelectorRefLoad(selectorName);
subIGF.Builder.CreateRet(selectorValue);
}
});

idValue = fn;
idResolution = KeyPathComponentHeader::FunctionCall;
} else {
Expand Down
4 changes: 3 additions & 1 deletion lib/IRGen/GenOpaque.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1354,6 +1354,7 @@ irgen::getOrCreateGetExtraInhabitantTagFunction(IRGenModule &IGM,
auto fn = llvm::Function::Create(fnTy, llvm::Function::PrivateLinkage,
"__swift_get_extra_inhabitant_index",
&IGM.Module);
fn->setAttributes(IGM.constructInitialAttributes());
fn->setCallingConv(IGM.SwiftCC);
IRGenFunction IGF(IGM, fn);
auto parameters = IGF.collectParameters();
Expand Down Expand Up @@ -1427,8 +1428,9 @@ irgen::getOrCreateStoreExtraInhabitantTagFunction(IRGenModule &IGM,

// TODO: use a meaningful mangled name and internal/shared linkage.
auto fn = llvm::Function::Create(fnTy, llvm::Function::PrivateLinkage,
"__swift_get_extra_inhabitant_index",
"__swift_store_extra_inhabitant_index",
&IGM.Module);
fn->setAttributes(IGM.constructInitialAttributes());
fn->setCallingConv(IGM.SwiftCC);
IRGenFunction IGF(IGM, fn);
auto parameters = IGF.collectParameters();
Expand Down
1 change: 1 addition & 0 deletions lib/IRGen/IRGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1407,6 +1407,7 @@ void IRGenModule::emitAutolinkInfo() {
llvm::Function::Create(llvm::FunctionType::get(VoidTy, false),
llvm::GlobalValue::ExternalLinkage, buf,
&Module);
ForceImportThunk->setAttributes(constructInitialAttributes());
ApplyIRLinkage(IRLinkage::ExternalExport).to(ForceImportThunk);
if (Triple.supportsCOMDAT())
if (auto *GO = cast<llvm::GlobalObject>(ForceImportThunk))
Expand Down
Loading