#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/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 {
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:
TargetLibraryInfoImpl();
explicit TargetLibraryInfoImpl(const Triple &T);
///
/// 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);
+
+ /// 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
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.
TargetLibraryInfoImpl::TargetLibraryInfoImpl(const TargetLibraryInfoImpl &TLI)
: CustomNames(TLI.CustomNames) {
memcpy(AvailableArray, TLI.AvailableArray, sizeof(AvailableArray));
+ VectorDescs = TLI.VectorDescs;
+ ScalarDescs = TLI.ScalarDescs;
}
TargetLibraryInfoImpl::TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI)
: CustomNames(std::move(TLI.CustomNames)) {
std::move(std::begin(TLI.AvailableArray), std::end(TLI.AvailableArray),
AvailableArray);
+ VectorDescs = TLI.VectorDescs;
+ ScalarDescs = TLI.ScalarDescs;
}
TargetLibraryInfoImpl &TargetLibraryInfoImpl::operator=(const TargetLibraryInfoImpl &TLI) {
memset(AvailableArray, 0, sizeof(AvailableArray));
}
+static bool compareByScalarFnName(const VecDesc &LHS, const VecDesc &RHS) {
+ return std::strncmp(LHS.ScalarFnName, RHS.ScalarFnName,
+ std::strlen(RHS.ScalarFnName)) < 0;
+}
+
+static bool compareByVectorFnName(const VecDesc &LHS, const VecDesc &RHS) {
+ return std::strncmp(LHS.VectorFnName, RHS.VectorFnName,
+ std::strlen(RHS.VectorFnName)) < 0;
+}
+
+static bool compareWithScalarFnName(const VecDesc &LHS, StringRef S) {
+ return std::strncmp(LHS.ScalarFnName, S.data(), S.size()) < 0;
+}
+
+static bool compareWithVectorFnName(const VecDesc &LHS, StringRef S) {
+ return std::strncmp(LHS.VectorFnName, S.data(), S.size()) < 0;
+}
+
+void TargetLibraryInfoImpl::addVectorizableFunctions(ArrayRef<VecDesc> Fns) {
+ VectorDescs.insert(VectorDescs.end(), Fns.begin(), Fns.end());
+ std::sort(VectorDescs.begin(), VectorDescs.end(), compareByScalarFnName);
+
+ ScalarDescs.insert(ScalarDescs.end(), Fns.begin(), Fns.end());
+ std::sort(ScalarDescs.begin(), ScalarDescs.end(), compareByVectorFnName);
+}
+
+bool TargetLibraryInfoImpl::isFunctionVectorizable(StringRef funcName) const {
+ funcName = sanitizeFunctionName(funcName);
+ if (funcName.empty())
+ return false;
+
+ std::vector<VecDesc>::const_iterator I = std::lower_bound(
+ VectorDescs.begin(), VectorDescs.end(), funcName,
+ compareWithScalarFnName);
+ return I != VectorDescs.end() && StringRef(I->ScalarFnName) == funcName;
+}
+
+StringRef TargetLibraryInfoImpl::getVectorizedFunction(StringRef F,
+ unsigned VF) const {
+ F = sanitizeFunctionName(F);
+ if (F.empty())
+ return F;
+ std::vector<VecDesc>::const_iterator I = std::lower_bound(
+ VectorDescs.begin(), VectorDescs.end(), F, compareWithScalarFnName);
+ while (I != VectorDescs.end() && StringRef(I->ScalarFnName) == F) {
+ if (I->VectorizationFactor == VF)
+ return I->VectorFnName;
+ ++I;
+ }
+ return StringRef();
+}
+
+StringRef TargetLibraryInfoImpl::getScalarizedFunction(StringRef F,
+ unsigned &VF) const {
+ F = sanitizeFunctionName(F);
+ if (F.empty())
+ return F;
+
+ std::vector<VecDesc>::const_iterator I = std::lower_bound(
+ ScalarDescs.begin(), ScalarDescs.end(), F, compareWithVectorFnName);
+ if (I == VectorDescs.end() || StringRef(I->VectorFnName) != F)
+ return StringRef();
+ VF = I->VectorizationFactor;
+ return I->ScalarFnName;
+}
+
TargetLibraryInfo TargetLibraryAnalysis::run(Module &M) {
if (PresetInfoImpl)
return TargetLibraryInfo(*PresetInfoImpl);