Skip to content

Cache LLVM attributes for intrinsics #21006

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 3 commits into from
Dec 4, 2018
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
11 changes: 7 additions & 4 deletions include/swift/AST/Builtins.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ StringRef getBuiltinBaseName(ASTContext &C, StringRef Name,
SmallVectorImpl<Type> &Types);

/// Given an LLVM IR intrinsic name with argument types remove (e.g. like
/// "bswap") return the LLVM IR IntrinsicID for the intrinsic or 0 if the
/// intrinsic name doesn't match anything.
unsigned getLLVMIntrinsicID(StringRef Name);
/// "bswap") return the LLVM IR IntrinsicID for the intrinsic or not_intrinsic
/// (0) if the intrinsic name doesn't match anything.
llvm::Intrinsic::ID getLLVMIntrinsicID(StringRef Name);

/// Get the LLVM intrinsic ID that corresponds to the given builtin with
/// overflow.
Expand All @@ -107,7 +107,10 @@ class BuiltinInfo {
};

/// \brief The information identifying the llvm intrinsic - its id and types.
struct IntrinsicInfo {
class IntrinsicInfo {
mutable llvm::AttributeList Attrs =
llvm::DenseMapInfo<llvm::AttributeList>::getEmptyKey();
public:
llvm::Intrinsic::ID ID;
SmallVector<Type, 4> Types;
bool hasAttribute(llvm::Attribute::AttrKind Kind) const;
Expand Down
31 changes: 13 additions & 18 deletions lib/AST/Builtins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,12 @@ bool BuiltinInfo::isReadNone() const {
}

bool IntrinsicInfo::hasAttribute(llvm::Attribute::AttrKind Kind) const {
// FIXME: We should not be relying on the global LLVM context.
llvm::AttributeList attrs =
llvm::Intrinsic::getAttributes(getGlobalLLVMContext(), ID);
return (attrs.hasAttribute(llvm::AttributeList::FunctionIndex, Kind));
using DenseMapInfo = llvm::DenseMapInfo<llvm::AttributeList>;
if (DenseMapInfo::isEqual(Attrs, DenseMapInfo::getEmptyKey())) {
// FIXME: We should not be relying on the global LLVM context.
Attrs = llvm::Intrinsic::getAttributes(getGlobalLLVMContext(), ID);
}
return Attrs.hasFnAttribute(Kind);
}

Type swift::getBuiltinType(ASTContext &Context, StringRef Name) {
Expand Down Expand Up @@ -1223,10 +1225,7 @@ static const char *const IntrinsicNameTable[] = {
#include "llvm/IR/IntrinsicImpl.inc"
#undef GET_INTRINSIC_TARGET_DATA

/// getLLVMIntrinsicID - Given an LLVM IR intrinsic name with argument types
/// removed (e.g. like "bswap") return the LLVM IR IntrinsicID for the intrinsic
/// or 0 if the intrinsic name doesn't match anything.
unsigned swift::getLLVMIntrinsicID(StringRef InName) {
llvm::Intrinsic::ID swift::getLLVMIntrinsicID(StringRef InName) {
using namespace llvm;

// Swift intrinsic names start with int_.
Expand Down Expand Up @@ -1319,12 +1318,11 @@ static Type DecodeIntrinsicType(ArrayRef<llvm::Intrinsic::IITDescriptor> &Table,

/// \returns true on success, false on failure.
static bool
getSwiftFunctionTypeForIntrinsic(unsigned iid, ArrayRef<Type> TypeArgs,
getSwiftFunctionTypeForIntrinsic(llvm::Intrinsic::ID ID,
ArrayRef<Type> TypeArgs,
ASTContext &Context,
SmallVectorImpl<Type> &ArgElts,
Type &ResultTy, FunctionType::ExtInfo &Info) {
llvm::Intrinsic::ID ID = (llvm::Intrinsic::ID)iid;

Type &ResultTy) {
typedef llvm::Intrinsic::IITDescriptor IITDescriptor;
SmallVector<IITDescriptor, 8> Table;
getIntrinsicInfoTableEntries(ID, Table);
Expand All @@ -1346,7 +1344,6 @@ getSwiftFunctionTypeForIntrinsic(unsigned iid, ArrayRef<Type> TypeArgs,
// Translate LLVM function attributes to Swift function attributes.
llvm::AttributeList attrs =
llvm::Intrinsic::getAttributes(getGlobalLLVMContext(), ID);
Info = FunctionType::ExtInfo();
if (attrs.hasAttribute(llvm::AttributeList::FunctionIndex,
llvm::Attribute::NoReturn)) {
ResultTy = Context.getNeverType();
Expand Down Expand Up @@ -1437,13 +1434,11 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) {

// If this is the name of an LLVM intrinsic, cons up a swift function with a
// type that matches the IR types.
if (unsigned ID = getLLVMIntrinsicID(OperationName)) {
if (llvm::Intrinsic::ID ID = getLLVMIntrinsicID(OperationName)) {
SmallVector<Type, 8> ArgElts;
Type ResultTy;
FunctionType::ExtInfo Info;
if (getSwiftFunctionTypeForIntrinsic(ID, Types, Context, ArgElts, ResultTy,
Info))
return getBuiltinFunction(Id, ArgElts, ResultTy, Info);
if (getSwiftFunctionTypeForIntrinsic(ID, Types, Context, ArgElts, ResultTy))
return getBuiltinFunction(Id, ArgElts, ResultTy);
}

// If this starts with fence, we have special suffixes to handle.
Expand Down
2 changes: 1 addition & 1 deletion lib/SIL/SILModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ const IntrinsicInfo &SILModule::getIntrinsicInfo(Identifier ID) {

// Otherwise, lookup the ID and Type and store them in the map.
StringRef NameRef = getBuiltinBaseName(getASTContext(), ID.str(), Info.Types);
Info.ID = (llvm::Intrinsic::ID)getLLVMIntrinsicID(NameRef);
Info.ID = getLLVMIntrinsicID(NameRef);

return Info;
}
Expand Down