mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
[TLI] Support for per-Function TLI that overrides available libfuncs
Summary: Follow-on to D66428 and D71193, to build the TLI per-function so that -fno-builtin* handling can be migrated to use function attributes. See discussion on D61634 for background. This is an enabler for fixing handling of these options for LTO, for example. With D71193, the -fno-builtin* flags are converted to function attributes, so we can now set this information per-function on the TLI. In this patch, the TLI constructor is changed to take a Function, which can be used to override the available builtins. The TLI is augmented with an array that can be used to specify which builtins are not available for the corresponding function. The available function checks are changed to consult this override before checking the underlying module level baseline TLII. New code is added to set this override array based on the attributes. I also removed the code that sets availability in the TLII in clang from the options, which is no longer needed. I removed a per-Triple caching of TLII objects in the analysis object, as it is based on the Module's Triple which is the same for all functions in any case. Is there a case where we would be compiling multiple Modules with different Triples in one compilation? Finally, I have changed the legacy analysis wrapper to create and use the new PM analysis class (TargetLibraryAnalysis) in getTLI. This is consistent with the behavior of getTTI for the legacy TargetTransformInfo analysis. This change means that getTLI now creates a new TLI on each call (although that should be very cheap as we cache the module level TLII, and computing the per-function attribute based availability should also be reasonably efficient). I measured the compile time for a large C++ file with tens of thousands of functions and as expected there was no increase. Reviewers: chandlerc, hfinkel, gchatelet Subscribers: mehdi_amini, dexonsmith, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D67923
This commit is contained in:
parent
659842608c
commit
b928562516
@ -9,6 +9,7 @@
|
||||
#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"
|
||||
@ -212,20 +213,50 @@ class TargetLibraryInfo {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -248,9 +279,27 @@ public:
|
||||
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);
|
||||
@ -265,7 +314,7 @@ public:
|
||||
/// 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;
|
||||
@ -295,7 +344,7 @@ public:
|
||||
}
|
||||
|
||||
StringRef getName(LibFunc F) const {
|
||||
auto State = Impl->getState(F);
|
||||
auto State = getState(F);
|
||||
if (State == TargetLibraryInfoImpl::Unavailable)
|
||||
return StringRef();
|
||||
if (State == TargetLibraryInfoImpl::StandardName)
|
||||
@ -363,29 +412,24 @@ public:
|
||||
/// 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();
|
||||
|
||||
@ -395,12 +439,10 @@ public:
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1588,22 +1588,12 @@ StringRef TargetLibraryInfoImpl::getScalarizedFunction(StringRef F,
|
||||
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 {
|
||||
@ -1614,18 +1604,18 @@ 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());
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user