#ifndef LLVM_ANALYSIS_TARGETLIBRARYINFO_H
#define LLVM_ANALYSIS_TARGETLIBRARYINFO_H
+#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/Triple.h"
friend class TargetLibraryAnalysis;
friend class TargetLibraryInfoWrapperPass;
+ /// The global (module level) TLI info.
const TargetLibraryInfoImpl *Impl;
+ /// Support for -fno-builtin* options as function attributes, overrides
+ /// information in global TargetLibraryInfoImpl.
+ BitVector OverrideAsUnavailable;
+
public:
- explicit TargetLibraryInfo(const TargetLibraryInfoImpl &Impl) : Impl(&Impl) {}
+ 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);
+ }
+ }
+ }
// Provide value semantics.
- TargetLibraryInfo(const TargetLibraryInfo &TLI) : Impl(TLI.Impl) {}
- TargetLibraryInfo(TargetLibraryInfo &&TLI) : Impl(TLI.Impl) {}
+ TargetLibraryInfo(const TargetLibraryInfo &TLI)
+ : Impl(TLI.Impl), OverrideAsUnavailable(TLI.OverrideAsUnavailable) {}
+ TargetLibraryInfo(TargetLibraryInfo &&TLI)
+ : Impl(TLI.Impl), OverrideAsUnavailable(TLI.OverrideAsUnavailable) {}
TargetLibraryInfo &operator=(const TargetLibraryInfo &TLI) {
Impl = TLI.Impl;
+ OverrideAsUnavailable = TLI.OverrideAsUnavailable;
return *this;
}
TargetLibraryInfo &operator=(TargetLibraryInfo &&TLI) {
Impl = TLI.Impl;
+ OverrideAsUnavailable = TLI.OverrideAsUnavailable;
return *this;
}
getLibFunc(*(CS.getCalledFunction()), F);
}
+ /// Disables all builtins.
+ ///
+ /// This can be used for options like -fno-builtin.
+ void disableAllFunctions() LLVM_ATTRIBUTE_UNUSED {
+ OverrideAsUnavailable.set();
+ }
+
+ /// Forces a function to be marked as unavailable.
+ void setUnavailable(LibFunc F) LLVM_ATTRIBUTE_UNUSED {
+ OverrideAsUnavailable.set(F);
+ }
+
+ TargetLibraryInfoImpl::AvailabilityState getState(LibFunc F) const {
+ if (OverrideAsUnavailable[F])
+ return TargetLibraryInfoImpl::Unavailable;
+ return Impl->getState(F);
+ }
+
/// Tests whether a library function is available.
bool has(LibFunc F) const {
- return Impl->getState(F) != TargetLibraryInfoImpl::Unavailable;
+ return getState(F) != TargetLibraryInfoImpl::Unavailable;
}
bool isFunctionVectorizable(StringRef F, unsigned VF) const {
return Impl->isFunctionVectorizable(F, VF);
/// Tests if the function is both available and a candidate for optimized code
/// generation.
bool hasOptimizedCodeGen(LibFunc F) const {
- if (Impl->getState(F) == TargetLibraryInfoImpl::Unavailable)
+ if (getState(F) == TargetLibraryInfoImpl::Unavailable)
return false;
switch (F) {
default: break;
}
StringRef getName(LibFunc F) const {
- auto State = Impl->getState(F);
+ auto State = getState(F);
if (State == TargetLibraryInfoImpl::Unavailable)
return StringRef();
if (State == TargetLibraryInfoImpl::StandardName)
/// module.
TargetLibraryAnalysis() {}
- /// Construct a library analysis with preset info.
+ /// Construct a library analysis with baseline Module-level info.
///
- /// This will directly copy the preset info into the result without
- /// consulting the module's triple.
- TargetLibraryAnalysis(TargetLibraryInfoImpl PresetInfoImpl)
- : PresetInfoImpl(std::move(PresetInfoImpl)) {}
+ /// This will be supplemented with Function-specific info in the Result.
+ TargetLibraryAnalysis(TargetLibraryInfoImpl BaselineInfoImpl)
+ : BaselineInfoImpl(std::move(BaselineInfoImpl)) {}
- TargetLibraryInfo run(Function &F, FunctionAnalysisManager &);
+ TargetLibraryInfo run(const Function &F, FunctionAnalysisManager &);
private:
friend AnalysisInfoMixin<TargetLibraryAnalysis>;
static AnalysisKey Key;
- Optional<TargetLibraryInfoImpl> PresetInfoImpl;
-
- StringMap<std::unique_ptr<TargetLibraryInfoImpl>> Impls;
-
- TargetLibraryInfoImpl &lookupInfoImpl(const Triple &T);
+ Optional<TargetLibraryInfoImpl> BaselineInfoImpl;
};
class TargetLibraryInfoWrapperPass : public ImmutablePass {
- TargetLibraryInfoImpl TLIImpl;
- TargetLibraryInfo TLI;
+ TargetLibraryAnalysis TLA;
+ Optional<TargetLibraryInfo> TLI;
virtual void anchor();
explicit TargetLibraryInfoWrapperPass(const Triple &T);
explicit TargetLibraryInfoWrapperPass(const TargetLibraryInfoImpl &TLI);
- TargetLibraryInfo &getTLI(const Function &F LLVM_ATTRIBUTE_UNUSED) {
- return TLI;
- }
- const TargetLibraryInfo &
- getTLI(const Function &F LLVM_ATTRIBUTE_UNUSED) const {
- return TLI;
+ TargetLibraryInfo &getTLI(const Function &F) {
+ FunctionAnalysisManager DummyFAM;
+ TLI = TLA.run(F, DummyFAM);
+ return *TLI;
}
};
return I->ScalarFnName;
}
-TargetLibraryInfo TargetLibraryAnalysis::run(Function &F,
+TargetLibraryInfo TargetLibraryAnalysis::run(const Function &F,
FunctionAnalysisManager &) {
- if (PresetInfoImpl)
- return TargetLibraryInfo(*PresetInfoImpl);
-
- return TargetLibraryInfo(
- lookupInfoImpl(Triple(F.getParent()->getTargetTriple())));
-}
-
-TargetLibraryInfoImpl &TargetLibraryAnalysis::lookupInfoImpl(const Triple &T) {
- std::unique_ptr<TargetLibraryInfoImpl> &Impl =
- Impls[T.normalize()];
- if (!Impl)
- Impl.reset(new TargetLibraryInfoImpl(T));
-
- return *Impl;
+ if (!BaselineInfoImpl)
+ BaselineInfoImpl =
+ TargetLibraryInfoImpl(Triple(F.getParent()->getTargetTriple()));
+ return TargetLibraryInfo(*BaselineInfoImpl, &F);
}
unsigned TargetLibraryInfoImpl::getWCharSize(const Module &M) const {
}
TargetLibraryInfoWrapperPass::TargetLibraryInfoWrapperPass()
- : ImmutablePass(ID), TLIImpl(), TLI(TLIImpl) {
+ : ImmutablePass(ID), TLA(TargetLibraryInfoImpl()) {
initializeTargetLibraryInfoWrapperPassPass(*PassRegistry::getPassRegistry());
}
TargetLibraryInfoWrapperPass::TargetLibraryInfoWrapperPass(const Triple &T)
- : ImmutablePass(ID), TLIImpl(T), TLI(TLIImpl) {
+ : ImmutablePass(ID), TLA(TargetLibraryInfoImpl(T)) {
initializeTargetLibraryInfoWrapperPassPass(*PassRegistry::getPassRegistry());
}
TargetLibraryInfoWrapperPass::TargetLibraryInfoWrapperPass(
const TargetLibraryInfoImpl &TLIImpl)
- : ImmutablePass(ID), TLIImpl(TLIImpl), TLI(this->TLIImpl) {
+ : ImmutablePass(ID), TLA(TLIImpl) {
initializeTargetLibraryInfoWrapperPassPass(*PassRegistry::getPassRegistry());
}