Home | History | Annotate | Line # | Download | only in Analysis
      1 //===-- TargetLibraryInfo.h - Library information ---------------*- C++ -*-===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 
      9 #ifndef LLVM_ANALYSIS_TARGETLIBRARYINFO_H
     10 #define LLVM_ANALYSIS_TARGETLIBRARYINFO_H
     11 
     12 #include "llvm/ADT/BitVector.h"
     13 #include "llvm/ADT/DenseMap.h"
     14 #include "llvm/ADT/Optional.h"
     15 #include "llvm/IR/Function.h"
     16 #include "llvm/IR/InstrTypes.h"
     17 #include "llvm/IR/Module.h"
     18 #include "llvm/IR/PassManager.h"
     19 #include "llvm/Pass.h"
     20 
     21 namespace llvm {
     22 template <typename T> class ArrayRef;
     23 class Triple;
     24 
     25 /// Describes a possible vectorization of a function.
     26 /// Function 'VectorFnName' is equivalent to 'ScalarFnName' vectorized
     27 /// by a factor 'VectorizationFactor'.
     28 struct VecDesc {
     29   StringRef ScalarFnName;
     30   StringRef VectorFnName;
     31   ElementCount VectorizationFactor;
     32 };
     33 
     34   enum LibFunc : unsigned {
     35 #define TLI_DEFINE_ENUM
     36 #include "llvm/Analysis/TargetLibraryInfo.def"
     37 
     38     NumLibFuncs,
     39     NotLibFunc
     40   };
     41 
     42 /// Implementation of the target library information.
     43 ///
     44 /// This class constructs tables that hold the target library information and
     45 /// make it available. However, it is somewhat expensive to compute and only
     46 /// depends on the triple. So users typically interact with the \c
     47 /// TargetLibraryInfo wrapper below.
     48 class TargetLibraryInfoImpl {
     49   friend class TargetLibraryInfo;
     50 
     51   unsigned char AvailableArray[(NumLibFuncs+3)/4];
     52   llvm::DenseMap<unsigned, std::string> CustomNames;
     53   static StringLiteral const StandardNames[NumLibFuncs];
     54   bool ShouldExtI32Param, ShouldExtI32Return, ShouldSignExtI32Param;
     55 
     56   enum AvailabilityState {
     57     StandardName = 3, // (memset to all ones)
     58     CustomName = 1,
     59     Unavailable = 0  // (memset to all zeros)
     60   };
     61   void setState(LibFunc F, AvailabilityState State) {
     62     AvailableArray[F/4] &= ~(3 << 2*(F&3));
     63     AvailableArray[F/4] |= State << 2*(F&3);
     64   }
     65   AvailabilityState getState(LibFunc F) const {
     66     return static_cast<AvailabilityState>((AvailableArray[F/4] >> 2*(F&3)) & 3);
     67   }
     68 
     69   /// Vectorization descriptors - sorted by ScalarFnName.
     70   std::vector<VecDesc> VectorDescs;
     71   /// Scalarization descriptors - same content as VectorDescs but sorted based
     72   /// on VectorFnName rather than ScalarFnName.
     73   std::vector<VecDesc> ScalarDescs;
     74 
     75   /// Return true if the function type FTy is valid for the library function
     76   /// F, regardless of whether the function is available.
     77   bool isValidProtoForLibFunc(const FunctionType &FTy, LibFunc F,
     78                               const DataLayout *DL) const;
     79 
     80 public:
     81   /// List of known vector-functions libraries.
     82   ///
     83   /// The vector-functions library defines, which functions are vectorizable
     84   /// and with which factor. The library can be specified by either frontend,
     85   /// or a commandline option, and then used by
     86   /// addVectorizableFunctionsFromVecLib for filling up the tables of
     87   /// vectorizable functions.
     88   enum VectorLibrary {
     89     NoLibrary,        // Don't use any vector library.
     90     Accelerate,       // Use Accelerate framework.
     91     DarwinLibSystemM, // Use Darwin's libsystem_m.
     92     LIBMVEC_X86,      // GLIBC Vector Math library.
     93     MASSV,            // IBM MASS vector library.
     94     SVML              // Intel short vector math library.
     95   };
     96 
     97   TargetLibraryInfoImpl();
     98   explicit TargetLibraryInfoImpl(const Triple &T);
     99 
    100   // Provide value semantics.
    101   TargetLibraryInfoImpl(const TargetLibraryInfoImpl &TLI);
    102   TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI);
    103   TargetLibraryInfoImpl &operator=(const TargetLibraryInfoImpl &TLI);
    104   TargetLibraryInfoImpl &operator=(TargetLibraryInfoImpl &&TLI);
    105 
    106   /// Searches for a particular function name.
    107   ///
    108   /// If it is one of the known library functions, return true and set F to the
    109   /// corresponding value.
    110   bool getLibFunc(StringRef funcName, LibFunc &F) const;
    111 
    112   /// Searches for a particular function name, also checking that its type is
    113   /// valid for the library function matching that name.
    114   ///
    115   /// If it is one of the known library functions, return true and set F to the
    116   /// corresponding value.
    117   bool getLibFunc(const Function &FDecl, LibFunc &F) const;
    118 
    119   /// Forces a function to be marked as unavailable.
    120   void setUnavailable(LibFunc F) {
    121     setState(F, Unavailable);
    122   }
    123 
    124   /// Forces a function to be marked as available.
    125   void setAvailable(LibFunc F) {
    126     setState(F, StandardName);
    127   }
    128 
    129   /// Forces a function to be marked as available and provide an alternate name
    130   /// that must be used.
    131   void setAvailableWithName(LibFunc F, StringRef Name) {
    132     if (StandardNames[F] != Name) {
    133       setState(F, CustomName);
    134       CustomNames[F] = std::string(Name);
    135       assert(CustomNames.find(F) != CustomNames.end());
    136     } else {
    137       setState(F, StandardName);
    138     }
    139   }
    140 
    141   /// Disables all builtins.
    142   ///
    143   /// This can be used for options like -fno-builtin.
    144   void disableAllFunctions();
    145 
    146   /// Add a set of scalar -> vector mappings, queryable via
    147   /// getVectorizedFunction and getScalarizedFunction.
    148   void addVectorizableFunctions(ArrayRef<VecDesc> Fns);
    149 
    150   /// Calls addVectorizableFunctions with a known preset of functions for the
    151   /// given vector library.
    152   void addVectorizableFunctionsFromVecLib(enum VectorLibrary VecLib);
    153 
    154   /// Return true if the function F has a vector equivalent with vectorization
    155   /// factor VF.
    156   bool isFunctionVectorizable(StringRef F, const ElementCount &VF) const {
    157     return !getVectorizedFunction(F, VF).empty();
    158   }
    159 
    160   /// Return true if the function F has a vector equivalent with any
    161   /// vectorization factor.
    162   bool isFunctionVectorizable(StringRef F) const;
    163 
    164   /// Return the name of the equivalent of F, vectorized with factor VF. If no
    165   /// such mapping exists, return the empty string.
    166   StringRef getVectorizedFunction(StringRef F, const ElementCount &VF) const;
    167 
    168   /// Set to true iff i32 parameters to library functions should have signext
    169   /// or zeroext attributes if they correspond to C-level int or unsigned int,
    170   /// respectively.
    171   void setShouldExtI32Param(bool Val) {
    172     ShouldExtI32Param = Val;
    173   }
    174 
    175   /// Set to true iff i32 results from library functions should have signext
    176   /// or zeroext attributes if they correspond to C-level int or unsigned int,
    177   /// respectively.
    178   void setShouldExtI32Return(bool Val) {
    179     ShouldExtI32Return = Val;
    180   }
    181 
    182   /// Set to true iff i32 parameters to library functions should have signext
    183   /// attribute if they correspond to C-level int or unsigned int.
    184   void setShouldSignExtI32Param(bool Val) {
    185     ShouldSignExtI32Param = Val;
    186   }
    187 
    188   /// Returns the size of the wchar_t type in bytes or 0 if the size is unknown.
    189   /// This queries the 'wchar_size' metadata.
    190   unsigned getWCharSize(const Module &M) const;
    191 
    192   /// Returns the largest vectorization factor used in the list of
    193   /// vector functions.
    194   void getWidestVF(StringRef ScalarF, ElementCount &FixedVF,
    195                    ElementCount &Scalable) const;
    196 
    197   /// Returns true if call site / callee has cdecl-compatible calling
    198   /// conventions.
    199   static bool isCallingConvCCompatible(CallBase *CI);
    200   static bool isCallingConvCCompatible(Function *Callee);
    201 };
    202 
    203 /// Provides information about what library functions are available for
    204 /// the current target.
    205 ///
    206 /// This both allows optimizations to handle them specially and frontends to
    207 /// disable such optimizations through -fno-builtin etc.
    208 class TargetLibraryInfo {
    209   friend class TargetLibraryAnalysis;
    210   friend class TargetLibraryInfoWrapperPass;
    211 
    212   /// The global (module level) TLI info.
    213   const TargetLibraryInfoImpl *Impl;
    214 
    215   /// Support for -fno-builtin* options as function attributes, overrides
    216   /// information in global TargetLibraryInfoImpl.
    217   BitVector OverrideAsUnavailable;
    218 
    219 public:
    220   explicit TargetLibraryInfo(const TargetLibraryInfoImpl &Impl,
    221                              Optional<const Function *> F = None)
    222       : Impl(&Impl), OverrideAsUnavailable(NumLibFuncs) {
    223     if (!F)
    224       return;
    225     if ((*F)->hasFnAttribute("no-builtins"))
    226       disableAllFunctions();
    227     else {
    228       // Disable individual libc/libm calls in TargetLibraryInfo.
    229       LibFunc LF;
    230       AttributeSet FnAttrs = (*F)->getAttributes().getFnAttributes();
    231       for (const Attribute &Attr : FnAttrs) {
    232         if (!Attr.isStringAttribute())
    233           continue;
    234         auto AttrStr = Attr.getKindAsString();
    235         if (!AttrStr.consume_front("no-builtin-"))
    236           continue;
    237         if (getLibFunc(AttrStr, LF))
    238           setUnavailable(LF);
    239       }
    240     }
    241   }
    242 
    243   // Provide value semantics.
    244   TargetLibraryInfo(const TargetLibraryInfo &TLI)
    245       : Impl(TLI.Impl), OverrideAsUnavailable(TLI.OverrideAsUnavailable) {}
    246   TargetLibraryInfo(TargetLibraryInfo &&TLI)
    247       : Impl(TLI.Impl), OverrideAsUnavailable(TLI.OverrideAsUnavailable) {}
    248   TargetLibraryInfo &operator=(const TargetLibraryInfo &TLI) {
    249     Impl = TLI.Impl;
    250     OverrideAsUnavailable = TLI.OverrideAsUnavailable;
    251     return *this;
    252   }
    253   TargetLibraryInfo &operator=(TargetLibraryInfo &&TLI) {
    254     Impl = TLI.Impl;
    255     OverrideAsUnavailable = TLI.OverrideAsUnavailable;
    256     return *this;
    257   }
    258 
    259   /// Determine whether a callee with the given TLI can be inlined into
    260   /// caller with this TLI, based on 'nobuiltin' attributes. When requested,
    261   /// allow inlining into a caller with a superset of the callee's nobuiltin
    262   /// attributes, which is conservatively correct.
    263   bool areInlineCompatible(const TargetLibraryInfo &CalleeTLI,
    264                            bool AllowCallerSuperset) const {
    265     if (!AllowCallerSuperset)
    266       return OverrideAsUnavailable == CalleeTLI.OverrideAsUnavailable;
    267     BitVector B = OverrideAsUnavailable;
    268     B |= CalleeTLI.OverrideAsUnavailable;
    269     // We can inline if the union of the caller and callee's nobuiltin
    270     // attributes is no stricter than the caller's nobuiltin attributes.
    271     return B == OverrideAsUnavailable;
    272   }
    273 
    274   /// Searches for a particular function name.
    275   ///
    276   /// If it is one of the known library functions, return true and set F to the
    277   /// corresponding value.
    278   bool getLibFunc(StringRef funcName, LibFunc &F) const {
    279     return Impl->getLibFunc(funcName, F);
    280   }
    281 
    282   bool getLibFunc(const Function &FDecl, LibFunc &F) const {
    283     return Impl->getLibFunc(FDecl, F);
    284   }
    285 
    286   /// If a callbase does not have the 'nobuiltin' attribute, return if the
    287   /// called function is a known library function and set F to that function.
    288   bool getLibFunc(const CallBase &CB, LibFunc &F) const {
    289     return !CB.isNoBuiltin() && CB.getCalledFunction() &&
    290            getLibFunc(*(CB.getCalledFunction()), F);
    291   }
    292 
    293   /// Disables all builtins.
    294   ///
    295   /// This can be used for options like -fno-builtin.
    296   void disableAllFunctions() LLVM_ATTRIBUTE_UNUSED {
    297     OverrideAsUnavailable.set();
    298   }
    299 
    300   /// Forces a function to be marked as unavailable.
    301   void setUnavailable(LibFunc F) LLVM_ATTRIBUTE_UNUSED {
    302     OverrideAsUnavailable.set(F);
    303   }
    304 
    305   TargetLibraryInfoImpl::AvailabilityState getState(LibFunc F) const {
    306     if (OverrideAsUnavailable[F])
    307       return TargetLibraryInfoImpl::Unavailable;
    308     return Impl->getState(F);
    309   }
    310 
    311   /// Tests whether a library function is available.
    312   bool has(LibFunc F) const {
    313     return getState(F) != TargetLibraryInfoImpl::Unavailable;
    314   }
    315   bool isFunctionVectorizable(StringRef F, const ElementCount &VF) const {
    316     return Impl->isFunctionVectorizable(F, VF);
    317   }
    318   bool isFunctionVectorizable(StringRef F) const {
    319     return Impl->isFunctionVectorizable(F);
    320   }
    321   StringRef getVectorizedFunction(StringRef F, const ElementCount &VF) const {
    322     return Impl->getVectorizedFunction(F, VF);
    323   }
    324 
    325   /// Tests if the function is both available and a candidate for optimized code
    326   /// generation.
    327   bool hasOptimizedCodeGen(LibFunc F) const {
    328     if (getState(F) == TargetLibraryInfoImpl::Unavailable)
    329       return false;
    330     switch (F) {
    331     default: break;
    332     case LibFunc_copysign:     case LibFunc_copysignf:  case LibFunc_copysignl:
    333     case LibFunc_fabs:         case LibFunc_fabsf:      case LibFunc_fabsl:
    334     case LibFunc_sin:          case LibFunc_sinf:       case LibFunc_sinl:
    335     case LibFunc_cos:          case LibFunc_cosf:       case LibFunc_cosl:
    336     case LibFunc_sqrt:         case LibFunc_sqrtf:      case LibFunc_sqrtl:
    337     case LibFunc_sqrt_finite:  case LibFunc_sqrtf_finite:
    338                                                    case LibFunc_sqrtl_finite:
    339     case LibFunc_fmax:         case LibFunc_fmaxf:      case LibFunc_fmaxl:
    340     case LibFunc_fmin:         case LibFunc_fminf:      case LibFunc_fminl:
    341     case LibFunc_floor:        case LibFunc_floorf:     case LibFunc_floorl:
    342     case LibFunc_nearbyint:    case LibFunc_nearbyintf: case LibFunc_nearbyintl:
    343     case LibFunc_ceil:         case LibFunc_ceilf:      case LibFunc_ceill:
    344     case LibFunc_rint:         case LibFunc_rintf:      case LibFunc_rintl:
    345     case LibFunc_round:        case LibFunc_roundf:     case LibFunc_roundl:
    346     case LibFunc_trunc:        case LibFunc_truncf:     case LibFunc_truncl:
    347     case LibFunc_log2:         case LibFunc_log2f:      case LibFunc_log2l:
    348     case LibFunc_exp2:         case LibFunc_exp2f:      case LibFunc_exp2l:
    349     case LibFunc_memcpy:       case LibFunc_memset:     case LibFunc_memmove:
    350     case LibFunc_memcmp:       case LibFunc_bcmp:       case LibFunc_strcmp:
    351     case LibFunc_strcpy:       case LibFunc_stpcpy:     case LibFunc_strlen:
    352     case LibFunc_strnlen:      case LibFunc_memchr:     case LibFunc_mempcpy:
    353       return true;
    354     }
    355     return false;
    356   }
    357 
    358   StringRef getName(LibFunc F) const {
    359     auto State = getState(F);
    360     if (State == TargetLibraryInfoImpl::Unavailable)
    361       return StringRef();
    362     if (State == TargetLibraryInfoImpl::StandardName)
    363       return Impl->StandardNames[F];
    364     assert(State == TargetLibraryInfoImpl::CustomName);
    365     return Impl->CustomNames.find(F)->second;
    366   }
    367 
    368   /// Returns extension attribute kind to be used for i32 parameters
    369   /// corresponding to C-level int or unsigned int.  May be zeroext, signext,
    370   /// or none.
    371   Attribute::AttrKind getExtAttrForI32Param(bool Signed = true) const {
    372     if (Impl->ShouldExtI32Param)
    373       return Signed ? Attribute::SExt : Attribute::ZExt;
    374     if (Impl->ShouldSignExtI32Param)
    375       return Attribute::SExt;
    376     return Attribute::None;
    377   }
    378 
    379   /// Returns extension attribute kind to be used for i32 return values
    380   /// corresponding to C-level int or unsigned int.  May be zeroext, signext,
    381   /// or none.
    382   Attribute::AttrKind getExtAttrForI32Return(bool Signed = true) const {
    383     if (Impl->ShouldExtI32Return)
    384       return Signed ? Attribute::SExt : Attribute::ZExt;
    385     return Attribute::None;
    386   }
    387 
    388   /// \copydoc TargetLibraryInfoImpl::getWCharSize()
    389   unsigned getWCharSize(const Module &M) const {
    390     return Impl->getWCharSize(M);
    391   }
    392 
    393   /// Handle invalidation from the pass manager.
    394   ///
    395   /// If we try to invalidate this info, just return false. It cannot become
    396   /// invalid even if the module or function changes.
    397   bool invalidate(Module &, const PreservedAnalyses &,
    398                   ModuleAnalysisManager::Invalidator &) {
    399     return false;
    400   }
    401   bool invalidate(Function &, const PreservedAnalyses &,
    402                   FunctionAnalysisManager::Invalidator &) {
    403     return false;
    404   }
    405   /// Returns the largest vectorization factor used in the list of
    406   /// vector functions.
    407   void getWidestVF(StringRef ScalarF, ElementCount &FixedVF,
    408                    ElementCount &ScalableVF) const {
    409     Impl->getWidestVF(ScalarF, FixedVF, ScalableVF);
    410   }
    411 
    412   /// Check if the function "F" is listed in a library known to LLVM.
    413   bool isKnownVectorFunctionInLibrary(StringRef F) const {
    414     return this->isFunctionVectorizable(F);
    415   }
    416 };
    417 
    418 /// Analysis pass providing the \c TargetLibraryInfo.
    419 ///
    420 /// Note that this pass's result cannot be invalidated, it is immutable for the
    421 /// life of the module.
    422 class TargetLibraryAnalysis : public AnalysisInfoMixin<TargetLibraryAnalysis> {
    423 public:
    424   typedef TargetLibraryInfo Result;
    425 
    426   /// Default construct the library analysis.
    427   ///
    428   /// This will use the module's triple to construct the library info for that
    429   /// module.
    430   TargetLibraryAnalysis() {}
    431 
    432   /// Construct a library analysis with baseline Module-level info.
    433   ///
    434   /// This will be supplemented with Function-specific info in the Result.
    435   TargetLibraryAnalysis(TargetLibraryInfoImpl BaselineInfoImpl)
    436       : BaselineInfoImpl(std::move(BaselineInfoImpl)) {}
    437 
    438   TargetLibraryInfo run(const Function &F, FunctionAnalysisManager &);
    439 
    440 private:
    441   friend AnalysisInfoMixin<TargetLibraryAnalysis>;
    442   static AnalysisKey Key;
    443 
    444   Optional<TargetLibraryInfoImpl> BaselineInfoImpl;
    445 };
    446 
    447 class TargetLibraryInfoWrapperPass : public ImmutablePass {
    448   TargetLibraryAnalysis TLA;
    449   Optional<TargetLibraryInfo> TLI;
    450 
    451   virtual void anchor();
    452 
    453 public:
    454   static char ID;
    455   TargetLibraryInfoWrapperPass();
    456   explicit TargetLibraryInfoWrapperPass(const Triple &T);
    457   explicit TargetLibraryInfoWrapperPass(const TargetLibraryInfoImpl &TLI);
    458 
    459   TargetLibraryInfo &getTLI(const Function &F) {
    460     FunctionAnalysisManager DummyFAM;
    461     TLI = TLA.run(F, DummyFAM);
    462     return *TLI;
    463   }
    464 };
    465 
    466 } // end namespace llvm
    467 
    468 #endif
    469