mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-30 16:17:05 +00:00 
			
		
		
		
	Also, add several entries to vectorizable functions table, and corresponding tests. The table isn't complete, it'll be populated later. Review: http://reviews.llvm.org/D8131 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@232531 91177308-0d34-0410-b5e6-96231b3b80d8
		
			
				
	
	
		
			329 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			329 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| //===-- TargetLibraryInfo.h - Library information ---------------*- C++ -*-===//
 | |
| //
 | |
| //                     The LLVM Compiler Infrastructure
 | |
| //
 | |
| // This file is distributed under the University of Illinois Open Source
 | |
| // License. See LICENSE.TXT for details.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #ifndef LLVM_ANALYSIS_TARGETLIBRARYINFO_H
 | |
| #define LLVM_ANALYSIS_TARGETLIBRARYINFO_H
 | |
| 
 | |
| #include "llvm/ADT/DenseMap.h"
 | |
| #include "llvm/ADT/ArrayRef.h"
 | |
| #include "llvm/ADT/Optional.h"
 | |
| #include "llvm/ADT/Triple.h"
 | |
| #include "llvm/IR/Function.h"
 | |
| #include "llvm/IR/Module.h"
 | |
| #include "llvm/Pass.h"
 | |
| 
 | |
| namespace llvm {
 | |
| /// VecDesc - Describes a possible vectorization of a function.
 | |
| /// Function 'VectorFnName' is equivalent to 'ScalarFnName' vectorized
 | |
| /// by a factor 'VectorizationFactor'.
 | |
| struct VecDesc {
 | |
|   const char *ScalarFnName;
 | |
|   const char *VectorFnName;
 | |
|   unsigned VectorizationFactor;
 | |
| };
 | |
| class PreservedAnalyses;
 | |
| 
 | |
|   namespace LibFunc {
 | |
|     enum Func {
 | |
| #define TLI_DEFINE_ENUM
 | |
| #include "llvm/Analysis/TargetLibraryInfo.def"
 | |
| 
 | |
|       NumLibFuncs
 | |
|     };
 | |
|   }
 | |
| 
 | |
| /// \brief Implementation of the target library information.
 | |
| ///
 | |
| /// This class constructs tables that hold the target library information and
 | |
| /// make it available. However, it is somewhat expensive to compute and only
 | |
| /// depends on the triple. So users typicaly interact with the \c
 | |
| /// TargetLibraryInfo wrapper below.
 | |
| class TargetLibraryInfoImpl {
 | |
|   friend class TargetLibraryInfo;
 | |
| 
 | |
|   unsigned char AvailableArray[(LibFunc::NumLibFuncs+3)/4];
 | |
|   llvm::DenseMap<unsigned, std::string> CustomNames;
 | |
|   static const char *const StandardNames[LibFunc::NumLibFuncs];
 | |
| 
 | |
|   enum AvailabilityState {
 | |
|     StandardName = 3, // (memset to all ones)
 | |
|     CustomName = 1,
 | |
|     Unavailable = 0  // (memset to all zeros)
 | |
|   };
 | |
|   void setState(LibFunc::Func F, AvailabilityState State) {
 | |
|     AvailableArray[F/4] &= ~(3 << 2*(F&3));
 | |
|     AvailableArray[F/4] |= State << 2*(F&3);
 | |
|   }
 | |
|   AvailabilityState getState(LibFunc::Func F) const {
 | |
|     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;
 | |
| 
 | |
| public:
 | |
|   /// \brief  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.
 | |
|   };
 | |
| 
 | |
|   TargetLibraryInfoImpl();
 | |
|   explicit TargetLibraryInfoImpl(const Triple &T);
 | |
| 
 | |
|   // Provide value semantics.
 | |
|   TargetLibraryInfoImpl(const TargetLibraryInfoImpl &TLI);
 | |
|   TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI);
 | |
|   TargetLibraryInfoImpl &operator=(const TargetLibraryInfoImpl &TLI);
 | |
|   TargetLibraryInfoImpl &operator=(TargetLibraryInfoImpl &&TLI);
 | |
| 
 | |
|   /// \brief Searches for a particular function name.
 | |
|   ///
 | |
|   /// If it is one of the known library functions, return true and set F to the
 | |
|   /// corresponding value.
 | |
|   bool getLibFunc(StringRef funcName, LibFunc::Func &F) const;
 | |
| 
 | |
|   /// \brief Forces a function to be marked as unavailable.
 | |
|   void setUnavailable(LibFunc::Func F) {
 | |
|     setState(F, Unavailable);
 | |
|   }
 | |
| 
 | |
|   /// \brief Forces a function to be marked as available.
 | |
|   void setAvailable(LibFunc::Func F) {
 | |
|     setState(F, StandardName);
 | |
|   }
 | |
| 
 | |
|   /// \brief Forces a function to be marked as available and provide an
 | |
|   /// alternate name that must be used.
 | |
|   void setAvailableWithName(LibFunc::Func F, StringRef Name) {
 | |
|     if (StandardNames[F] != Name) {
 | |
|       setState(F, CustomName);
 | |
|       CustomNames[F] = Name;
 | |
|       assert(CustomNames.find(F) != CustomNames.end());
 | |
|     } else {
 | |
|       setState(F, StandardName);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /// \brief Disables all builtins.
 | |
|   ///
 | |
|   /// This can be used for options like -fno-builtin.
 | |
|   void disableAllFunctions();
 | |
| 
 | |
|   /// addVectorizableFunctions - 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);
 | |
| 
 | |
|   /// isFunctionVectorizable - 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();
 | |
|   }
 | |
| 
 | |
|   /// isFunctionVectorizable - Return true if the function F has a
 | |
|   /// vector equivalent with any vectorization factor.
 | |
|   bool isFunctionVectorizable(StringRef F) const;
 | |
| 
 | |
|   /// getVectorizedFunction - 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;
 | |
| 
 | |
|   /// isFunctionScalarizable - 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();
 | |
|   }
 | |
| 
 | |
|   /// getScalarizedFunction - 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;
 | |
| };
 | |
| 
 | |
| /// \brief Provides information about what library functions are available for
 | |
| /// the current target.
 | |
| ///
 | |
| /// This both allows optimizations to handle them specially and frontends to
 | |
| /// disable such optimizations through -fno-builtin etc.
 | |
| class TargetLibraryInfo {
 | |
|   friend class TargetLibraryAnalysis;
 | |
|   friend class TargetLibraryInfoWrapperPass;
 | |
| 
 | |
|   const TargetLibraryInfoImpl *Impl;
 | |
| 
 | |
| public:
 | |
|   explicit TargetLibraryInfo(const TargetLibraryInfoImpl &Impl) : Impl(&Impl) {}
 | |
| 
 | |
|   // Provide value semantics.
 | |
|   TargetLibraryInfo(const TargetLibraryInfo &TLI) : Impl(TLI.Impl) {}
 | |
|   TargetLibraryInfo(TargetLibraryInfo &&TLI) : Impl(TLI.Impl) {}
 | |
|   TargetLibraryInfo &operator=(const TargetLibraryInfo &TLI) {
 | |
|     Impl = TLI.Impl;
 | |
|     return *this;
 | |
|   }
 | |
|   TargetLibraryInfo &operator=(TargetLibraryInfo &&TLI) {
 | |
|     Impl = TLI.Impl;
 | |
|     return *this;
 | |
|   }
 | |
| 
 | |
|   /// \brief Searches for a particular function name.
 | |
|   ///
 | |
|   /// If it is one of the known library functions, return true and set F to the
 | |
|   /// corresponding value.
 | |
|   bool getLibFunc(StringRef funcName, LibFunc::Func &F) const {
 | |
|     return Impl->getLibFunc(funcName, F);
 | |
|   }
 | |
| 
 | |
|   /// \brief Tests whether a library function is available.
 | |
|   bool has(LibFunc::Func F) const {
 | |
|     return Impl->getState(F) != TargetLibraryInfoImpl::Unavailable;
 | |
|   }
 | |
|   bool isFunctionVectorizable(StringRef F, unsigned VF) const {
 | |
|     return Impl->isFunctionVectorizable(F, VF);
 | |
|   };
 | |
|   bool isFunctionVectorizable(StringRef F) const {
 | |
|     return Impl->isFunctionVectorizable(F);
 | |
|   };
 | |
|   StringRef getVectorizedFunction(StringRef F, unsigned VF) const {
 | |
|     return Impl->getVectorizedFunction(F, VF);
 | |
|   };
 | |
| 
 | |
|   /// \brief Tests if the function is both available and a candidate for
 | |
|   /// optimized code generation.
 | |
|   bool hasOptimizedCodeGen(LibFunc::Func F) const {
 | |
|     if (Impl->getState(F) == TargetLibraryInfoImpl::Unavailable)
 | |
|       return false;
 | |
|     switch (F) {
 | |
|     default: break;
 | |
|     case LibFunc::copysign:  case LibFunc::copysignf:  case LibFunc::copysignl:
 | |
|     case LibFunc::fabs:      case LibFunc::fabsf:      case LibFunc::fabsl:
 | |
|     case LibFunc::sin:       case LibFunc::sinf:       case LibFunc::sinl:
 | |
|     case LibFunc::cos:       case LibFunc::cosf:       case LibFunc::cosl:
 | |
|     case LibFunc::sqrt:      case LibFunc::sqrtf:      case LibFunc::sqrtl:
 | |
|     case LibFunc::sqrt_finite: case LibFunc::sqrtf_finite:
 | |
|                                                   case LibFunc::sqrtl_finite:
 | |
|     case LibFunc::fmax:      case LibFunc::fmaxf:      case LibFunc::fmaxl:
 | |
|     case LibFunc::fmin:      case LibFunc::fminf:      case LibFunc::fminl:
 | |
|     case LibFunc::floor:     case LibFunc::floorf:     case LibFunc::floorl:
 | |
|     case LibFunc::nearbyint: case LibFunc::nearbyintf: case LibFunc::nearbyintl:
 | |
|     case LibFunc::ceil:      case LibFunc::ceilf:      case LibFunc::ceill:
 | |
|     case LibFunc::rint:      case LibFunc::rintf:      case LibFunc::rintl:
 | |
|     case LibFunc::round:     case LibFunc::roundf:     case LibFunc::roundl:
 | |
|     case LibFunc::trunc:     case LibFunc::truncf:     case LibFunc::truncl:
 | |
|     case LibFunc::log2:      case LibFunc::log2f:      case LibFunc::log2l:
 | |
|     case LibFunc::exp2:      case LibFunc::exp2f:      case LibFunc::exp2l:
 | |
|     case LibFunc::memcmp:    case LibFunc::strcmp:     case LibFunc::strcpy:
 | |
|     case LibFunc::stpcpy:    case LibFunc::strlen:     case LibFunc::strnlen:
 | |
|     case LibFunc::memchr:
 | |
|       return true;
 | |
|     }
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   StringRef getName(LibFunc::Func F) const {
 | |
|     auto State = Impl->getState(F);
 | |
|     if (State == TargetLibraryInfoImpl::Unavailable)
 | |
|       return StringRef();
 | |
|     if (State == TargetLibraryInfoImpl::StandardName)
 | |
|       return Impl->StandardNames[F];
 | |
|     assert(State == TargetLibraryInfoImpl::CustomName);
 | |
|     return Impl->CustomNames.find(F)->second;
 | |
|   }
 | |
| 
 | |
|   /// \brief Handle invalidation from the pass manager.
 | |
|   ///
 | |
|   /// If we try to invalidate this info, just return false. It cannot become
 | |
|   /// invalid even if the module changes.
 | |
|   bool invalidate(Module &, const PreservedAnalyses &) { return false; }
 | |
| };
 | |
| 
 | |
| /// \brief Analysis pass providing the \c TargetLibraryInfo.
 | |
| ///
 | |
| /// Note that this pass's result cannot be invalidated, it is immutable for the
 | |
| /// life of the module.
 | |
| class TargetLibraryAnalysis {
 | |
| public:
 | |
|   typedef TargetLibraryInfo Result;
 | |
| 
 | |
|   /// \brief Opaque, unique identifier for this analysis pass.
 | |
|   static void *ID() { return (void *)&PassID; }
 | |
| 
 | |
|   /// \brief Default construct the library analysis.
 | |
|   ///
 | |
|   /// This will use the module's triple to construct the library info for that
 | |
|   /// module.
 | |
|   TargetLibraryAnalysis() {}
 | |
| 
 | |
|   /// \brief Construct a library analysis with preset info.
 | |
|   ///
 | |
|   /// This will directly copy the preset info into the result without
 | |
|   /// consulting the module's triple.
 | |
|   TargetLibraryAnalysis(TargetLibraryInfoImpl PresetInfoImpl)
 | |
|       : PresetInfoImpl(std::move(PresetInfoImpl)) {}
 | |
| 
 | |
|   // Move semantics. We spell out the constructors for MSVC.
 | |
|   TargetLibraryAnalysis(TargetLibraryAnalysis &&Arg)
 | |
|       : PresetInfoImpl(std::move(Arg.PresetInfoImpl)), Impls(std::move(Arg.Impls)) {}
 | |
|   TargetLibraryAnalysis &operator=(TargetLibraryAnalysis &&RHS) {
 | |
|     PresetInfoImpl = std::move(RHS.PresetInfoImpl);
 | |
|     Impls = std::move(RHS.Impls);
 | |
|     return *this;
 | |
|   }
 | |
| 
 | |
|   TargetLibraryInfo run(Module &M);
 | |
|   TargetLibraryInfo run(Function &F);
 | |
| 
 | |
|   /// \brief Provide access to a name for this pass for debugging purposes.
 | |
|   static StringRef name() { return "TargetLibraryAnalysis"; }
 | |
| 
 | |
| private:
 | |
|   static char PassID;
 | |
| 
 | |
|   Optional<TargetLibraryInfoImpl> PresetInfoImpl;
 | |
| 
 | |
|   StringMap<std::unique_ptr<TargetLibraryInfoImpl>> Impls;
 | |
| 
 | |
|   TargetLibraryInfoImpl &lookupInfoImpl(Triple T);
 | |
| };
 | |
| 
 | |
| class TargetLibraryInfoWrapperPass : public ImmutablePass {
 | |
|   TargetLibraryInfoImpl TLIImpl;
 | |
|   TargetLibraryInfo TLI;
 | |
| 
 | |
|   virtual void anchor();
 | |
| 
 | |
| public:
 | |
|   static char ID;
 | |
|   TargetLibraryInfoWrapperPass();
 | |
|   explicit TargetLibraryInfoWrapperPass(const Triple &T);
 | |
|   explicit TargetLibraryInfoWrapperPass(const TargetLibraryInfoImpl &TLI);
 | |
| 
 | |
|   TargetLibraryInfo &getTLI() { return TLI; }
 | |
|   const TargetLibraryInfo &getTLI() const { return TLI; }
 | |
| };
 | |
| 
 | |
| } // end namespace llvm
 | |
| 
 | |
| #endif
 |