diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -1868,6 +1868,24 @@ llvm::for_each(NBA->builtinNames(), AddNoBuiltinAttr); } +static void addVectLibAttributes(llvm::AttrBuilder &FuncAttrs, + const CodeGenOptions &CodeGenOpts) { + StringRef AttributeName = "vect-lib"; + switch (CodeGenOpts.getVecLib()) { + case CodeGenOptions::Accelerate: + FuncAttrs.addAttribute(AttributeName, "Accelerate"); + break; + case CodeGenOptions::MASSV: + FuncAttrs.addAttribute(AttributeName, "MASSV"); + break; + case CodeGenOptions::SVML: + FuncAttrs.addAttribute(AttributeName, "SVML"); + break; + case CodeGenOptions::NoLibrary: + break; + } +} + void CodeGenModule::ConstructAttributeList( StringRef Name, const CGFunctionInfo &FI, CGCalleeInfo CalleeInfo, llvm::AttributeList &AttrList, unsigned &CallingConv, bool AttrOnCallSite) { @@ -1966,6 +1984,9 @@ // * FunctionDecl attributes: __attribute__((no_builtin(...))) addNoBuiltinAttributes(FuncAttrs, getLangOpts(), NBA); + // Attach "vect-lib" attribute to function based on '-fveclib' setting. + addVectLibAttributes(FuncAttrs, getCodeGenOpts()); + ConstructDefaultFnAttrList(Name, HasOptnone, AttrOnCallSite, FuncAttrs); // This must run after constructing the default function attribute list diff --git a/clang/test/CodeGen/libcalls-veclib.c b/clang/test/CodeGen/libcalls-veclib.c new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/libcalls-veclib.c @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -S -emit-llvm -fveclib=SVML -o - %s | FileCheck --check-prefixes=SVML %s +// RUN: %clang_cc1 -S -emit-llvm -fveclib=Accelerate -o - %s | FileCheck --check-prefixes=ACCELERATE %s +// RUN: %clang_cc1 -S -emit-llvm -fveclib=MASSV -o - %s | FileCheck --check-prefixes=MASSV %s +// RUN: %clang_cc1 -S -emit-llvm -fveclib=none -o - %s | FileCheck --check-prefixes=NOLIB %s +// RUN: %clang_cc1 -S -emit-llvm -o - %s | FileCheck --check-prefixes=NOLIB %s + +int main() { + return 0; +} + +// SVML: "vect-lib"="SVML" +// ACCELERATE: "vect-lib"="Accelerate" +// MASSV: "vect-lib"="MASSV" +// NOLIB-NOT: "vect-lib" \ No newline at end of file diff --git a/llvm/include/llvm/Analysis/TargetLibraryInfo.h b/llvm/include/llvm/Analysis/TargetLibraryInfo.h --- a/llvm/include/llvm/Analysis/TargetLibraryInfo.h +++ b/llvm/include/llvm/Analysis/TargetLibraryInfo.h @@ -48,6 +48,22 @@ class TargetLibraryInfoImpl { friend class TargetLibraryInfo; +public: + /// List of known vector-functions libraries. + /// + /// The vector-functions library defines, which functions are vectorizable + /// and with which factor. The library can be specified by either frontend, + /// or a commandline option, and then used by + /// addVectorizableFunctionsFromVecLib for filling up the tables of + /// vectorizable functions. + enum VectorLibrary { + NoLibrary, // Don't use any vector library. + Accelerate, // Use Accelerate framework. + MASSV, // IBM MASS vector library. + SVML // Intel short vector math library. + }; + +private: unsigned char AvailableArray[(NumLibFuncs+3)/4]; llvm::DenseMap CustomNames; static StringLiteral const StandardNames[NumLibFuncs]; @@ -71,6 +87,8 @@ /// Scalarization descriptors - same content as VectorDescs but sorted based /// on VectorFnName rather than ScalarFnName. std::vector ScalarDescs; + /// Vector library available for vectorization. + VectorLibrary VectLibrary = NoLibrary; /// Return true if the function type FTy is valid for the library function /// F, regardless of whether the function is available. @@ -78,20 +96,6 @@ const DataLayout *DL) const; public: - /// List of known vector-functions libraries. - /// - /// The vector-functions library defines, which functions are vectorizable - /// and with which factor. The library can be specified by either frontend, - /// or a commandline option, and then used by - /// addVectorizableFunctionsFromVecLib for filling up the tables of - /// vectorizable functions. - enum VectorLibrary { - NoLibrary, // Don't use any vector library. - Accelerate, // Use Accelerate framework. - MASSV, // IBM MASS vector library. - SVML // Intel short vector math library. - }; - TargetLibraryInfoImpl(); explicit TargetLibraryInfoImpl(const Triple &T); @@ -148,6 +152,7 @@ /// Calls addVectorizableFunctions with a known preset of functions for the /// given vector library. void addVectorizableFunctionsFromVecLib(enum VectorLibrary VecLib); + void addVectorizableFunctionsFromVecLib(const StringRef &VecLibName); /// Return true if the function F has a vector equivalent with vectorization /// factor VF. @@ -261,18 +266,20 @@ } /// Determine whether a callee with the given TLI can be inlined into - /// caller with this TLI, based on 'nobuiltin' attributes. When requested, - /// allow inlining into a caller with a superset of the callee's nobuiltin - /// attributes, which is conservatively correct. + /// caller with this TLI, based on 'nobuiltin', `vect-lib` attributes. + /// When requested, allow inlining into a caller with a superset of the + /// callee's attributes, which is conservatively correct. bool areInlineCompatible(const TargetLibraryInfo &CalleeTLI, bool AllowCallerSuperset) const { if (!AllowCallerSuperset) - return OverrideAsUnavailable == CalleeTLI.OverrideAsUnavailable; + return Impl->VectLibrary == CalleeTLI.Impl->VectLibrary && + OverrideAsUnavailable == CalleeTLI.OverrideAsUnavailable; BitVector B = OverrideAsUnavailable; B |= CalleeTLI.OverrideAsUnavailable; - // We can inline if the union of the caller and callee's nobuiltin - // attributes is no stricter than the caller's nobuiltin attributes. - return B == OverrideAsUnavailable; + // We can inline if the union of the caller and callee's attributes + // is no stricter than the caller's attributes. + return B == OverrideAsUnavailable && + CalleeTLI.Impl->VectLibrary == TargetLibraryInfoImpl::NoLibrary; } /// Searches for a particular function name. diff --git a/llvm/lib/Analysis/TargetLibraryInfo.cpp b/llvm/lib/Analysis/TargetLibraryInfo.cpp --- a/llvm/lib/Analysis/TargetLibraryInfo.cpp +++ b/llvm/lib/Analysis/TargetLibraryInfo.cpp @@ -1528,8 +1528,29 @@ llvm::sort(ScalarDescs, compareByVectorFnName); } +void TargetLibraryInfoImpl::addVectorizableFunctionsFromVecLib( + const StringRef &VecLibName) { + VectorLibrary VecLib = NoLibrary; + if (VecLibName == "Accelerate") + VecLib = Accelerate; + else if (VecLibName == "MASSV") + VecLib = MASSV; + else if (VecLibName == "SVML") + VecLib = SVML; + else + return; + addVectorizableFunctionsFromVecLib(VecLib); +} + void TargetLibraryInfoImpl::addVectorizableFunctionsFromVecLib( enum VectorLibrary VecLib) { + if (VectLibrary != NoLibrary) { + assert(VectLibrary == VecLib && + "Conflicting VectorLibrary detected"); + return; + } + + VectLibrary = VecLib; switch (VecLib) { case Accelerate: { const VecDesc VecFuncs[] = { @@ -1604,6 +1625,11 @@ if (!BaselineInfoImpl) BaselineInfoImpl = TargetLibraryInfoImpl(Triple(F.getParent()->getTargetTriple())); + + StringRef VectLibName = F.getFnAttribute("vect-lib").getValueAsString(); + if (!VectLibName.empty()) + BaselineInfoImpl->addVectorizableFunctionsFromVecLib(VectLibName); + return TargetLibraryInfo(*BaselineInfoImpl, &F); }