llvm-6502/include/llvm/Analysis/TargetLibraryInfo.h
Michael Zolotukhin 5850602050 TLI: Add addVectorizableFunctionsFromVecLib.
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
2015-03-17 19:50:55 +00:00

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