[llvm] 60c642e - [TLI] Per-function fveclib for math library used for vectorization

Wenlei He via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 9 18:26:54 PDT 2020


Author: Wenlei He
Date: 2020-04-09T18:26:38-07:00
New Revision: 60c642e74be6af86906d9f3d982728be7bd4329f

URL: https://github.com/llvm/llvm-project/commit/60c642e74be6af86906d9f3d982728be7bd4329f
DIFF: https://github.com/llvm/llvm-project/commit/60c642e74be6af86906d9f3d982728be7bd4329f.diff

LOG: [TLI] Per-function fveclib for math library used for vectorization

Summary:
Encode `-fveclib` setting as per-function attribute so it can threaded through to LTO backends. Accordingly per-function TLI now reads
the attributes and select available vector function list based on that. Now we also populate function list for all supported vector
libraries for the shared per-module `TargetLibraryInfoImpl`, so each function can select its available vector list independently but without
duplicating the vector function lists. Inlining between incompatbile vectlib attributed is also prohibited now.

Subscribers: hiraditya, dexonsmith, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D77632

Added: 
    clang/test/CodeGen/libcalls-veclib.c
    llvm/test/Transforms/Inline/veclib-compat.ll

Modified: 
    clang/lib/CodeGen/BackendUtil.cpp
    clang/lib/CodeGen/CGCall.cpp
    llvm/include/llvm/Analysis/TargetLibraryInfo.h
    llvm/lib/Analysis/InlineCost.cpp
    llvm/lib/Analysis/TargetLibraryInfo.cpp
    llvm/test/Transforms/Inline/inline-no-builtin-compatible.ll

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 8d2d5c1534fc..82c200ee6ae1 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -352,24 +352,8 @@ static void addMemTagOptimizationPasses(const PassManagerBuilder &Builder,
   PM.add(createStackSafetyGlobalInfoWrapperPass(/*SetMetadata=*/true));
 }
 
-static TargetLibraryInfoImpl *createTLII(llvm::Triple &TargetTriple,
-                                         const CodeGenOptions &CodeGenOpts) {
-  TargetLibraryInfoImpl *TLII = new TargetLibraryInfoImpl(TargetTriple);
-
-  switch (CodeGenOpts.getVecLib()) {
-  case CodeGenOptions::Accelerate:
-    TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::Accelerate);
-    break;
-  case CodeGenOptions::MASSV:
-    TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::MASSV);
-    break;
-  case CodeGenOptions::SVML:
-    TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::SVML);
-    break;
-  default:
-    break;
-  }
-  return TLII;
+static TargetLibraryInfoImpl *createTLII(llvm::Triple &TargetTriple) {
+  return new TargetLibraryInfoImpl(TargetTriple);
 }
 
 static void addSymbolRewriterPass(const CodeGenOptions &Opts,
@@ -562,8 +546,7 @@ void EmitAssemblyHelper::CreatePasses(legacy::PassManager &MPM,
   // are inserted before PMBuilder ones - they'd get the default-constructed
   // TLI with an unknown target otherwise.
   Triple TargetTriple(TheModule->getTargetTriple());
-  std::unique_ptr<TargetLibraryInfoImpl> TLII(
-      createTLII(TargetTriple, CodeGenOpts));
+  std::unique_ptr<TargetLibraryInfoImpl> TLII(createTLII(TargetTriple));
 
   // If we reached here with a non-empty index file name, then the index file
   // was empty and we are not performing ThinLTO backend compilation (used in
@@ -805,8 +788,7 @@ bool EmitAssemblyHelper::AddEmitPasses(legacy::PassManager &CodeGenPasses,
                                        raw_pwrite_stream *DwoOS) {
   // Add LibraryInfo.
   llvm::Triple TargetTriple(TheModule->getTargetTriple());
-  std::unique_ptr<TargetLibraryInfoImpl> TLII(
-      createTLII(TargetTriple, CodeGenOpts));
+  std::unique_ptr<TargetLibraryInfoImpl> TLII(createTLII(TargetTriple));
   CodeGenPasses.add(new TargetLibraryInfoWrapperPass(*TLII));
 
   // Normal mode, emit a .s or .o file by running the code generator. Note,
@@ -1142,8 +1124,7 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager(
   // Register the target library analysis directly and give it a customized
   // preset TLI.
   Triple TargetTriple(TheModule->getTargetTriple());
-  std::unique_ptr<TargetLibraryInfoImpl> TLII(
-      createTLII(TargetTriple, CodeGenOpts));
+  std::unique_ptr<TargetLibraryInfoImpl> TLII(createTLII(TargetTriple));
   FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); });
 
   // Register all the basic analyses with the managers.

diff  --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 3c44632dfd60..73869fa3c9b0 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -1868,6 +1868,24 @@ static void addNoBuiltinAttributes(llvm::AttrBuilder &FuncAttrs,
   llvm::for_each(NBA->builtinNames(), AddNoBuiltinAttr);
 }
 
+static void addVectLibAttributes(llvm::AttrBuilder &FuncAttrs,
+                                 const CodeGenOptions &CodeGenOpts) {
+  StringRef AttributeName = "veclib";
+  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 @@ void CodeGenModule::ConstructAttributeList(
   // * FunctionDecl attributes: __attribute__((no_builtin(...)))
   addNoBuiltinAttributes(FuncAttrs, getLangOpts(), NBA);
 
+  // Attach "veclib" 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
index 000000000000..505f6c00cecf
--- /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: "veclib"="SVML"
+// ACCELERATE: "veclib"="Accelerate"
+// MASSV: "veclib"="MASSV"
+// NOLIB-NOT: "veclib"
\ No newline at end of file

diff  --git a/llvm/include/llvm/Analysis/TargetLibraryInfo.h b/llvm/include/llvm/Analysis/TargetLibraryInfo.h
index 0860b7244dfd..cf87eb4f014c 100644
--- a/llvm/include/llvm/Analysis/TargetLibraryInfo.h
+++ b/llvm/include/llvm/Analysis/TargetLibraryInfo.h
@@ -48,6 +48,23 @@ struct VecDesc {
 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 {
+    Accelerate, // Use Accelerate framework.
+    MASSV,      // IBM MASS vector library.
+    SVML,       // Intel short vector math library.
+    NumVecLibs, // Number of supported vector libraries.
+    NoLibrary   // Don't use any vector library.
+  };
+
+private:
   unsigned char AvailableArray[(NumLibFuncs+3)/4];
   llvm::DenseMap<unsigned, std::string> CustomNames;
   static StringLiteral const StandardNames[NumLibFuncs];
@@ -66,32 +83,31 @@ class TargetLibraryInfoImpl {
     return static_cast<AvailabilityState>((AvailableArray[F/4] >> 2*(F&3)) & 3);
   }
 
-  /// Vectorization descriptors - sorted by ScalarFnName.
-  std::vector<VecDesc> VectorDescs;
-  /// Scalarization descriptors - same content as VectorDescs but sorted based
-  /// on VectorFnName rather than ScalarFnName.
-  std::vector<VecDesc> ScalarDescs;
+  /// Vector library descriptor for all supported ones.
+  struct VectorLibraryDescriptors {
+    /// Vectorization descriptors - sorted by ScalarFnName.
+    std::vector<VecDesc> VectorDescs;
+    /// Scalarization descriptors - same content as VectorDescs but sorted based
+    /// on VectorFnName rather than ScalarFnName.
+    std::vector<VecDesc> ScalarDescs;
+  } VecLibDescs[NumVecLibs];
 
   /// Return true if the function type FTy is valid for the library function
   /// F, regardless of whether the function is available.
   bool isValidProtoForLibFunc(const FunctionType &FTy, LibFunc F,
                               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.
-  };
+  /// Add a set of scalar -> vector mappings, queryable via
+  /// getVectorizedFunction and getScalarizedFunction.
+  void addVectorizableFunctions(ArrayRef<VecDesc> Fns,
+                                VectorLibraryDescriptors &VetLibDescs);
 
+  /// Calls addVectorizableFunctionsFromVecLib with a known preset of functions
+  /// for the given vector library.
+  void addVectorizableFunctionsFromVecLib(enum VectorLibrary VecLib,
+                                          VectorLibraryDescriptors &VetLibDesc);
+
+public:
   TargetLibraryInfoImpl();
   explicit TargetLibraryInfoImpl(const Triple &T);
 
@@ -141,39 +157,38 @@ class TargetLibraryInfoImpl {
   /// This can be used for options like -fno-builtin.
   void disableAllFunctions();
 
-  /// Add a set of scalar -> vector mappings, queryable via
-  /// getVectorizedFunction and getScalarizedFunction.
-  void addVectorizableFunctions(ArrayRef<VecDesc> Fns);
-
-  /// Calls addVectorizableFunctions with a known preset of functions for the
-  /// given vector library.
-  void addVectorizableFunctionsFromVecLib(enum VectorLibrary VecLib);
+  /// Populate VectorLibraryDescriptors for all supported vector libraries.
+  void addAllVectorizableFunctions();
 
   /// Return true if the function F has a vector equivalent with vectorization
   /// factor VF.
-  bool isFunctionVectorizable(StringRef F, unsigned VF) const {
-    return !getVectorizedFunction(F, VF).empty();
+  bool isFunctionVectorizable(StringRef F, unsigned VF,
+                              VectorLibrary vecLib) const {
+    return !getVectorizedFunction(F, VF, vecLib).empty();
   }
 
   /// Return true if the function F has a vector equivalent with any
   /// vectorization factor.
-  bool isFunctionVectorizable(StringRef F) const;
+  bool isFunctionVectorizable(StringRef F, VectorLibrary vecLib) const;
 
   /// Return the name of the equivalent of F, vectorized with factor VF. If no
   /// such mapping exists, return the empty string.
-  StringRef getVectorizedFunction(StringRef F, unsigned VF) const;
+  StringRef getVectorizedFunction(StringRef F, unsigned VF,
+                                  VectorLibrary vecLib) const;
 
   /// Return true if the function F has a scalar equivalent, and set VF to be
   /// the vectorization factor.
-  bool isFunctionScalarizable(StringRef F, unsigned &VF) const {
-    return !getScalarizedFunction(F, VF).empty();
+  bool isFunctionScalarizable(StringRef F, unsigned &VF,
+                              VectorLibrary vecLib) const {
+    return !getScalarizedFunction(F, VF, vecLib).empty();
   }
 
   /// Return the name of the equivalent of F, scalarized. If no such mapping
   /// exists, return the empty string.
   ///
   /// Set VF to the vectorization factor.
-  StringRef getScalarizedFunction(StringRef F, unsigned &VF) const;
+  StringRef getScalarizedFunction(StringRef F, unsigned &VF,
+                                  VectorLibrary vecLib) const;
 
   /// Set to true iff i32 parameters to library functions should have signext
   /// or zeroext attributes if they correspond to C-level int or unsigned int,
@@ -201,7 +216,7 @@ class TargetLibraryInfoImpl {
 
   /// Returns the largest vectorization factor used in the list of
   /// vector functions.
-  unsigned getWidestVF(StringRef ScalarF) const;
+  unsigned getWidestVF(StringRef ScalarF, VectorLibrary vecLib) const;
 };
 
 /// Provides information about what library functions are available for
@@ -216,63 +231,66 @@ class TargetLibraryInfo {
   /// The global (module level) TLI info.
   const TargetLibraryInfoImpl *Impl;
 
+  /// Vector library available for vectorization.
+  TargetLibraryInfoImpl::VectorLibrary VectLibrary =
+      TargetLibraryInfoImpl::NoLibrary;
+
   /// Support for -fno-builtin* options as function attributes, overrides
   /// information in global TargetLibraryInfoImpl.
   BitVector OverrideAsUnavailable;
 
+  TargetLibraryInfoImpl::VectorLibrary
+  getVecLibFromName(const StringRef &VecLibName) {
+    if (VecLibName == "Accelerate")
+      return TargetLibraryInfoImpl::Accelerate;
+    else if (VecLibName == "MASSV")
+      return TargetLibraryInfoImpl::MASSV;
+    else if (VecLibName == "SVML")
+      return TargetLibraryInfoImpl::SVML;
+    return TargetLibraryInfoImpl::NoLibrary;
+  }
+
 public:
   explicit TargetLibraryInfo(const TargetLibraryInfoImpl &Impl,
-                             Optional<const Function *> F = None)
-      : Impl(&Impl), OverrideAsUnavailable(NumLibFuncs) {
-    if (!F)
-      return;
-    if ((*F)->hasFnAttribute("no-builtins"))
-      disableAllFunctions();
-    else {
-      // Disable individual libc/libm calls in TargetLibraryInfo.
-      LibFunc LF;
-      AttributeSet FnAttrs = (*F)->getAttributes().getFnAttributes();
-      for (const Attribute &Attr : FnAttrs) {
-        if (!Attr.isStringAttribute())
-          continue;
-        auto AttrStr = Attr.getKindAsString();
-        if (!AttrStr.consume_front("no-builtin-"))
-          continue;
-        if (getLibFunc(AttrStr, LF))
-          setUnavailable(LF);
-      }
-    }
-  }
+                             Optional<const Function *> F = None);
 
   // Provide value semantics.
   TargetLibraryInfo(const TargetLibraryInfo &TLI)
-      : Impl(TLI.Impl), OverrideAsUnavailable(TLI.OverrideAsUnavailable) {}
+      : Impl(TLI.Impl), VectLibrary(TLI.VectLibrary),
+        OverrideAsUnavailable(TLI.OverrideAsUnavailable) {}
   TargetLibraryInfo(TargetLibraryInfo &&TLI)
-      : Impl(TLI.Impl), OverrideAsUnavailable(TLI.OverrideAsUnavailable) {}
+      : Impl(TLI.Impl), VectLibrary(TLI.VectLibrary),
+        OverrideAsUnavailable(TLI.OverrideAsUnavailable) {}
   TargetLibraryInfo &operator=(const TargetLibraryInfo &TLI) {
     Impl = TLI.Impl;
+    VectLibrary = TLI.VectLibrary;
     OverrideAsUnavailable = TLI.OverrideAsUnavailable;
     return *this;
   }
   TargetLibraryInfo &operator=(TargetLibraryInfo &&TLI) {
     Impl = TLI.Impl;
+    VectLibrary = TLI.VectLibrary;
     OverrideAsUnavailable = TLI.OverrideAsUnavailable;
     return *this;
   }
 
   /// 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', `veclib` 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 VectLibrary == CalleeTLI.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.
+    bool VecLibCompatible =
+        (VectLibrary == CalleeTLI.VectLibrary) ||
+        CalleeTLI.VectLibrary == TargetLibraryInfoImpl::NoLibrary;
+    return B == OverrideAsUnavailable && VecLibCompatible;
   }
 
   /// Searches for a particular function name.
@@ -317,13 +335,13 @@ class TargetLibraryInfo {
     return getState(F) != TargetLibraryInfoImpl::Unavailable;
   }
   bool isFunctionVectorizable(StringRef F, unsigned VF) const {
-    return Impl->isFunctionVectorizable(F, VF);
+    return Impl->isFunctionVectorizable(F, VF, VectLibrary);
   }
   bool isFunctionVectorizable(StringRef F) const {
-    return Impl->isFunctionVectorizable(F);
+    return Impl->isFunctionVectorizable(F, VectLibrary);
   }
   StringRef getVectorizedFunction(StringRef F, unsigned VF) const {
-    return Impl->getVectorizedFunction(F, VF);
+    return Impl->getVectorizedFunction(F, VF, VectLibrary);
   }
 
   /// Tests if the function is both available and a candidate for optimized code
@@ -408,7 +426,7 @@ class TargetLibraryInfo {
   /// Returns the largest vectorization factor used in the list of
   /// vector functions.
   unsigned getWidestVF(StringRef ScalarF) const {
-    return Impl->getWidestVF(ScalarF);
+    return Impl->getWidestVF(ScalarF, VectLibrary);
   }
 
   /// Check if the function "F" is listed in a library known to LLVM.

diff  --git a/llvm/lib/Analysis/InlineCost.cpp b/llvm/lib/Analysis/InlineCost.cpp
index b9f0699ab6f7..a96047ac80e9 100644
--- a/llvm/lib/Analysis/InlineCost.cpp
+++ b/llvm/lib/Analysis/InlineCost.cpp
@@ -104,10 +104,9 @@ static cl::opt<bool> OptComputeFullInlineCost(
     cl::desc("Compute the full inline cost of a call site even when the cost "
              "exceeds the threshold."));
 
-static cl::opt<bool> InlineCallerSupersetNoBuiltin(
-    "inline-caller-superset-nobuiltin", cl::Hidden, cl::init(true),
-    cl::ZeroOrMore,
-    cl::desc("Allow inlining when caller has a superset of callee's nobuiltin "
+static cl::opt<bool> InlineCallerSupersetTLI(
+    "inline-caller-superset-tli", cl::Hidden, cl::init(true), cl::ZeroOrMore,
+    cl::desc("Allow inlining when caller has a superset of callee's TLI "
              "attributes."));
 
 namespace {
@@ -2169,7 +2168,7 @@ static bool functionsHaveCompatibleAttributes(
   auto CalleeTLI = GetTLI(*Callee);
   return TTI.areInlineCompatible(Caller, Callee) &&
          GetTLI(*Caller).areInlineCompatible(CalleeTLI,
-                                             InlineCallerSupersetNoBuiltin) &&
+                                             InlineCallerSupersetTLI) &&
          AttributeFuncs::areInlineCompatible(*Caller, *Callee);
 }
 

diff  --git a/llvm/lib/Analysis/TargetLibraryInfo.cpp b/llvm/lib/Analysis/TargetLibraryInfo.cpp
index ffa6921c51be..ff61b5c4af49 100644
--- a/llvm/lib/Analysis/TargetLibraryInfo.cpp
+++ b/llvm/lib/Analysis/TargetLibraryInfo.cpp
@@ -550,7 +550,7 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T,
     TLI.setUnavailable(LibFunc_nvvm_reflect);
   }
 
-  TLI.addVectorizableFunctionsFromVecLib(ClVectorLibrary);
+  TLI.addAllVectorizableFunctions();
 }
 
 TargetLibraryInfoImpl::TargetLibraryInfoImpl() {
@@ -572,8 +572,8 @@ TargetLibraryInfoImpl::TargetLibraryInfoImpl(const TargetLibraryInfoImpl &TLI)
       ShouldExtI32Return(TLI.ShouldExtI32Return),
       ShouldSignExtI32Param(TLI.ShouldSignExtI32Param) {
   memcpy(AvailableArray, TLI.AvailableArray, sizeof(AvailableArray));
-  VectorDescs = TLI.VectorDescs;
-  ScalarDescs = TLI.ScalarDescs;
+  for (unsigned i = 0; i < NumVecLibs; i++)
+    VecLibDescs[i] = TLI.VecLibDescs[i];
 }
 
 TargetLibraryInfoImpl::TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI)
@@ -583,8 +583,8 @@ TargetLibraryInfoImpl::TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI)
       ShouldSignExtI32Param(TLI.ShouldSignExtI32Param) {
   std::move(std::begin(TLI.AvailableArray), std::end(TLI.AvailableArray),
             AvailableArray);
-  VectorDescs = TLI.VectorDescs;
-  ScalarDescs = TLI.ScalarDescs;
+  for (unsigned i = 0; i < NumVecLibs; i++)
+    VecLibDescs[i] = TLI.VecLibDescs[i];
 }
 
 TargetLibraryInfoImpl &TargetLibraryInfoImpl::operator=(const TargetLibraryInfoImpl &TLI) {
@@ -1520,7 +1520,16 @@ static bool compareWithVectorFnName(const VecDesc &LHS, StringRef S) {
   return LHS.VectorFnName < S;
 }
 
-void TargetLibraryInfoImpl::addVectorizableFunctions(ArrayRef<VecDesc> Fns) {
+void TargetLibraryInfoImpl::addAllVectorizableFunctions() {
+  addVectorizableFunctionsFromVecLib(Accelerate, VecLibDescs[Accelerate]);
+  addVectorizableFunctionsFromVecLib(MASSV, VecLibDescs[MASSV]);
+  addVectorizableFunctionsFromVecLib(SVML, VecLibDescs[SVML]);
+}
+
+void TargetLibraryInfoImpl::addVectorizableFunctions(
+    ArrayRef<VecDesc> Fns, VectorLibraryDescriptors &VecLibDesc) {
+  auto &VectorDescs = VecLibDesc.VectorDescs;
+  auto &ScalarDescs = VecLibDesc.ScalarDescs;
   VectorDescs.insert(VectorDescs.end(), Fns.begin(), Fns.end());
   llvm::sort(VectorDescs, compareByScalarFnName);
 
@@ -1529,14 +1538,14 @@ void TargetLibraryInfoImpl::addVectorizableFunctions(ArrayRef<VecDesc> Fns) {
 }
 
 void TargetLibraryInfoImpl::addVectorizableFunctionsFromVecLib(
-    enum VectorLibrary VecLib) {
+    enum VectorLibrary VecLib, VectorLibraryDescriptors &VetLibDesc) {
   switch (VecLib) {
   case Accelerate: {
     const VecDesc VecFuncs[] = {
     #define TLI_DEFINE_ACCELERATE_VECFUNCS
     #include "llvm/Analysis/VecFuncs.def"
     };
-    addVectorizableFunctions(VecFuncs);
+    addVectorizableFunctions(VecFuncs, VetLibDesc);
     break;
   }
   case MASSV: {
@@ -1544,7 +1553,7 @@ void TargetLibraryInfoImpl::addVectorizableFunctionsFromVecLib(
     #define TLI_DEFINE_MASSV_VECFUNCS
     #include "llvm/Analysis/VecFuncs.def"
     };
-    addVectorizableFunctions(VecFuncs);
+    addVectorizableFunctions(VecFuncs, VetLibDesc);
     break;
   }
   case SVML: {
@@ -1552,29 +1561,34 @@ void TargetLibraryInfoImpl::addVectorizableFunctionsFromVecLib(
     #define TLI_DEFINE_SVML_VECFUNCS
     #include "llvm/Analysis/VecFuncs.def"
     };
-    addVectorizableFunctions(VecFuncs);
+    addVectorizableFunctions(VecFuncs, VetLibDesc);
     break;
   }
-  case NoLibrary:
+  default:
+    llvm_unreachable("Unexpected vector library");
     break;
   }
 }
 
-bool TargetLibraryInfoImpl::isFunctionVectorizable(StringRef funcName) const {
+bool TargetLibraryInfoImpl::isFunctionVectorizable(StringRef funcName,
+                                                   VectorLibrary vecLib) const {
   funcName = sanitizeFunctionName(funcName);
-  if (funcName.empty())
+  if (funcName.empty() || vecLib >= NumVecLibs)
     return false;
 
+  auto &VectorDescs = VecLibDescs[vecLib].VectorDescs;
   std::vector<VecDesc>::const_iterator I =
       llvm::lower_bound(VectorDescs, funcName, compareWithScalarFnName);
   return I != VectorDescs.end() && StringRef(I->ScalarFnName) == funcName;
 }
 
-StringRef TargetLibraryInfoImpl::getVectorizedFunction(StringRef F,
-                                                       unsigned VF) const {
+StringRef
+TargetLibraryInfoImpl::getVectorizedFunction(StringRef F, unsigned VF,
+                                             VectorLibrary vecLib) const {
   F = sanitizeFunctionName(F);
-  if (F.empty())
+  if (F.empty() || vecLib >= NumVecLibs)
     return F;
+  auto &VectorDescs = VecLibDescs[vecLib].VectorDescs;
   std::vector<VecDesc>::const_iterator I =
       llvm::lower_bound(VectorDescs, F, compareWithScalarFnName);
   while (I != VectorDescs.end() && StringRef(I->ScalarFnName) == F) {
@@ -1585,12 +1599,15 @@ StringRef TargetLibraryInfoImpl::getVectorizedFunction(StringRef F,
   return StringRef();
 }
 
-StringRef TargetLibraryInfoImpl::getScalarizedFunction(StringRef F,
-                                                       unsigned &VF) const {
+StringRef
+TargetLibraryInfoImpl::getScalarizedFunction(StringRef F, unsigned &VF,
+                                             VectorLibrary vecLib) const {
   F = sanitizeFunctionName(F);
-  if (F.empty())
+  if (F.empty() || vecLib >= NumVecLibs)
     return F;
 
+  auto &VectorDescs = VecLibDescs[vecLib].VectorDescs;
+  auto &ScalarDescs = VecLibDescs[vecLib].ScalarDescs;
   std::vector<VecDesc>::const_iterator I =
       llvm::lower_bound(ScalarDescs, F, compareWithVectorFnName);
   if (I == VectorDescs.end() || StringRef(I->VectorFnName) != F)
@@ -1599,6 +1616,36 @@ StringRef TargetLibraryInfoImpl::getScalarizedFunction(StringRef F,
   return I->ScalarFnName;
 }
 
+TargetLibraryInfo::TargetLibraryInfo(const TargetLibraryInfoImpl &Impl,
+                                     Optional<const Function *> F)
+    : Impl(&Impl), OverrideAsUnavailable(NumLibFuncs) {
+  if (!F)
+    return;
+
+  StringRef VectLib = (*F)->getFnAttribute("veclib").getValueAsString();
+  if (!VectLib.empty())
+    VectLibrary = getVecLibFromName(VectLib);
+  else
+    VectLibrary = ClVectorLibrary;
+
+  if ((*F)->hasFnAttribute("no-builtins"))
+    disableAllFunctions();
+  else {
+    // Disable individual libc/libm calls in TargetLibraryInfo.
+    LibFunc LF;
+    AttributeSet FnAttrs = (*F)->getAttributes().getFnAttributes();
+    for (const Attribute &Attr : FnAttrs) {
+      if (!Attr.isStringAttribute())
+        continue;
+      auto AttrStr = Attr.getKindAsString();
+      if (!AttrStr.consume_front("no-builtin-"))
+        continue;
+      if (getLibFunc(AttrStr, LF))
+        setUnavailable(LF);
+    }
+  }
+}
+
 TargetLibraryInfo TargetLibraryAnalysis::run(const Function &F,
                                              FunctionAnalysisManager &) {
   if (!BaselineInfoImpl)
@@ -1639,12 +1686,14 @@ char TargetLibraryInfoWrapperPass::ID = 0;
 
 void TargetLibraryInfoWrapperPass::anchor() {}
 
-unsigned TargetLibraryInfoImpl::getWidestVF(StringRef ScalarF) const {
+unsigned TargetLibraryInfoImpl::getWidestVF(StringRef ScalarF,
+                                            VectorLibrary vecLib) const {
   ScalarF = sanitizeFunctionName(ScalarF);
-  if (ScalarF.empty())
+  if (ScalarF.empty() || vecLib >= NumVecLibs)
     return 1;
 
   unsigned VF = 1;
+  auto &VectorDescs = VecLibDescs[vecLib].VectorDescs;
   std::vector<VecDesc>::const_iterator I =
       llvm::lower_bound(VectorDescs, ScalarF, compareWithScalarFnName);
   while (I != VectorDescs.end() && StringRef(I->ScalarFnName) == ScalarF) {

diff  --git a/llvm/test/Transforms/Inline/inline-no-builtin-compatible.ll b/llvm/test/Transforms/Inline/inline-no-builtin-compatible.ll
index 2568cef15501..5e3767e76f77 100644
--- a/llvm/test/Transforms/Inline/inline-no-builtin-compatible.ll
+++ b/llvm/test/Transforms/Inline/inline-no-builtin-compatible.ll
@@ -3,8 +3,8 @@
 ; RUN: opt < %s -mtriple=x86_64-unknown-linux-gnu -S -passes='cgscc(inline)' | FileCheck %s
 
 ; Make sure we don't inline callees into a caller with a superset of the
-; no builtin attributes when -inline-caller-superset-nobuiltin=false.
-; RUN: opt < %s -inline-caller-superset-nobuiltin=false -mtriple=x86_64-unknown-linux-gnu -S -passes='cgscc(inline)' | FileCheck %s --check-prefix=NOSUPERSET
+; no builtin attributes when -inline-caller-superset-tli=false.
+; RUN: opt < %s -inline-caller-superset-tli=false -mtriple=x86_64-unknown-linux-gnu -S -passes='cgscc(inline)' | FileCheck %s --check-prefix=NOSUPERSET
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"

diff  --git a/llvm/test/Transforms/Inline/veclib-compat.ll b/llvm/test/Transforms/Inline/veclib-compat.ll
new file mode 100644
index 000000000000..03cfb7250545
--- /dev/null
+++ b/llvm/test/Transforms/Inline/veclib-compat.ll
@@ -0,0 +1,48 @@
+; RUN: opt < %s -inline -inline-caller-superset-tli=true -S | FileCheck %s --check-prefixes=COMMON
+; RUN: opt < %s -passes='cgscc(inline)' -inline-caller-superset-tli=true -S | FileCheck %s --check-prefixes=COMMON
+; RUN: opt < %s -inline -inline-caller-superset-tli=false -S | FileCheck %s --check-prefixes=NOSUPERSET,COMMON
+; RUN: opt < %s -passes='cgscc(inline)' -inline-caller-superset-tli=false -S | FileCheck %s --check-prefixes=NOSUPERSET,COMMON
+
+
+
+define i32 @callee_svml(i8 %X) #0 {
+entry:
+  ret i32 1
+}
+
+define i32 @callee_massv(i8 %X) #1 {
+entry:
+  ret i32 1
+}
+
+define i32 @callee_nolibrary(i8 %X) {
+entry:
+  ret i32 1
+}
+
+define i32 @caller_svml() #0 {
+; COMMON-LABEL: define i32 @caller_svml()
+entry:
+  %rslt = call i32 @callee_massv(i8 123)
+; COMMON: call i32 @callee_massv
+  %tmp1 = call i32 @callee_nolibrary(i8 123)
+; NOSUPERSET: call i32 @callee_nolibrary
+  %tmp2 = call i32 @callee_svml(i8 123)
+; COMMON-NOT: call
+  ret i32 %rslt
+}
+
+define i32 @caller_nolibrary() {
+; COMMON-LABEL: define i32 @caller_nolibrary()
+entry:
+  %rslt = call i32 @callee_svml(i8 123)
+; COMMON: call i32 @callee_svml
+  %tmp1 = call i32 @callee_massv(i8 123)
+; COMMON: call i32 @callee_massv
+  %tmp2 = call i32 @callee_nolibrary(i8 123)
+; COMMON-NOT: call
+  ret i32 %rslt
+}
+
+attributes #0 = { "veclib"="SVML" }
+attributes #1 = { "veclib"="MASSV" }
\ No newline at end of file


        


More information about the llvm-commits mailing list