<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Jan 23, 2015 at 6:06 PM, Chandler Carruth <span dir="ltr"><<a href="mailto:chandlerc@gmail.com" target="_blank">chandlerc@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: chandlerc<br>
Date: Fri Jan 23 20:06:09 2015<br>
New Revision: 226981<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=226981&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=226981&view=rev</a><br>
Log:<br>
[PM] Rework how the TargetLibraryInfo pass integrates with the new pass<br>
manager to support the actual uses of it. =]<br>
<br>
When I ported instcombine to the new pass manager I discover that it<br>
didn't work because TLI wasn't available in the right places. This is<br>
a somewhat surprising and/or subtle aspect of the new pass manager<br>
design that came up before but I think is useful to be reminded of:<br>
<br>
While the new pass manager *allows* a function pass to query a module<br>
analysis, it requires that the module analysis is already run and cached<br>
prior to the function pass manager starting up, possibly with<br>
a 'require<foo>' style utility in the pass pipeline. This is an<br>
intentional hurdle because using a module analysis from a function pass<br>
*requires* that the module analysis is run prior to entering the<br>
function pass manager. Otherwise the other functions in the module could<br>
be in who-knows-what state, etc.<br>
<br>
A somewhat surprising consequence of this design decision (at least to<br>
me) is that you have to design a function pass that leverages<br>
a module analysis to do so as an optional feature.</blockquote><div><br>What's the harm in having the function pass assert the module analysis is available? It sounds like making it conservatively correct could result in some function passes becoming no-ops in certain pass pipelines, which would seem annoying to debug compared to a hard assertion failure?<br><br>Anyway - curious to chat with you about this at some point, no doubt.<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> Even if that means<br>
your function pass does no work in the absence of the module analysis,<br>
you have to handle that possibility and remain conservatively correct.<br>
This is a natural consequence of things being able to invalidate the<br>
module analysis and us being unable to re-run it. And it's a generally<br>
good thing because it lets us reorder passes arbitrarily without<br>
breaking correctness, etc.<br>
<br>
This ends up causing problems in one case. What if we have a module<br>
analysis that is *definitionally* impossible to invalidate. In the<br>
places this might come up, the analysis is usually also definitionally<br>
trivial to run even while other transformation passes run on the module,<br>
regardless of the state of anything. And so, it follows that it is<br>
natural to have a hard requirement on such analyses from a function<br>
pass.<br>
<br>
It turns out, that TargetLibraryInfo is just such an analysis, and<br>
InstCombine has a hard requirement on it.<br>
<br>
The approach I've taken here is to produce an analysis that models this<br>
flexibility by making it both a module and a function analysis. This<br>
exposes the fact that it is in fact safe to compute at any point. We can<br>
even make it a valid CGSCC analysis at some point if that is useful.<br>
However, we don't want to have a copy of the actual target library info<br>
state for each function! This state is specific to the triple. The<br>
somewhat direct and blunt approach here is to turn TLI into a pimpl,<br>
with the state and mutators in the implementation class and the query<br>
routines primarily in the wrapper. Then the analysis can lazily<br>
construct and cache the implementations, keyed on the triple, and<br>
on-demand produce wrappers of them for each function.<br>
<br>
One minor annoyance is that we will end up with a wrapper for each<br>
function in the module. While this is a bit wasteful (one pointer per<br>
function) it seems tolerable. And it has the advantage of ensuring that<br>
we pay the absolute minimum synchronization cost to access this<br>
information should we end up with a nice parallel function pass manager<br>
in the future. We could look into trying to mark when analysis results<br>
are especially cheap to recompute and more eagerly GC-ing the cached<br>
results, or we could look at supporting a variant of analyses whose<br>
results are specifically *not* cached and expected to just be used and<br>
discarded by the consumer. Either way, these seem like incremental<br>
enhancements that should happen when we start profiling the memory and<br>
CPU usage of the new pass manager and not before.<br>
<br>
The other minor annoyance is that if we end up using the TLI in both<br>
a module pass and a function pass, those will be produced by two<br>
separate analyses, and thus will point to separate copies of the<br>
implementation state. While a minor issue, I dislike this and would like<br>
to find a way to cleanly allow a single analysis instance to be used<br>
across multiple IR unit managers. But I don't have a good solution to<br>
this today, and I don't want to hold up all of the work waiting to come<br>
up with one. This too seems like a reasonable thing to incrementally<br>
improve later.<br>
<br>
Modified:<br>
llvm/trunk/include/llvm/ADT/Triple.h<br>
llvm/trunk/include/llvm/Analysis/TargetLibraryInfo.h<br>
llvm/trunk/include/llvm/Transforms/IPO/PassManagerBuilder.h<br>
llvm/trunk/lib/Analysis/TargetLibraryInfo.cpp<br>
llvm/trunk/lib/LTO/LTOCodeGenerator.cpp<br>
llvm/trunk/lib/Target/Target.cpp<br>
llvm/trunk/tools/llc/llc.cpp<br>
llvm/trunk/tools/opt/PassRegistry.def<br>
llvm/trunk/tools/opt/opt.cpp<br>
<br>
Modified: llvm/trunk/include/llvm/ADT/Triple.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/Triple.h?rev=226981&r1=226980&r2=226981&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/Triple.h?rev=226981&r1=226980&r2=226981&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/ADT/Triple.h (original)<br>
+++ llvm/trunk/include/llvm/ADT/Triple.h Fri Jan 23 20:06:09 2015<br>
@@ -210,6 +210,9 @@ public:<br>
/// common case in which otherwise valid components are in the wrong order.<br>
static std::string normalize(StringRef Str);<br>
<br>
+ /// \brief Return the normalized form of this triple's string.<br>
+ std::string normalize() const { return normalize(Data); }<br>
+<br>
/// @}<br>
/// @name Typed Component Access<br>
/// @{<br>
<br>
Modified: llvm/trunk/include/llvm/Analysis/TargetLibraryInfo.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/TargetLibraryInfo.h?rev=226981&r1=226980&r2=226981&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/TargetLibraryInfo.h?rev=226981&r1=226980&r2=226981&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/Analysis/TargetLibraryInfo.h (original)<br>
+++ llvm/trunk/include/llvm/Analysis/TargetLibraryInfo.h Fri Jan 23 20:06:09 2015<br>
@@ -13,7 +13,7 @@<br>
#include "llvm/ADT/DenseMap.h"<br>
#include "llvm/ADT/Optional.h"<br>
#include "llvm/ADT/Triple.h"<br>
-#include "llvm/IR/Module.h"<br>
+#include "llvm/IR/Function.h"<br>
#include "llvm/IR/Module.h"<br>
#include "llvm/Pass.h"<br>
<br>
@@ -696,12 +696,15 @@ class PreservedAnalyses;<br>
};<br>
}<br>
<br>
-/// \brief Provides information about what library functions are available for<br>
-/// the current target.<br>
+/// \brief Implementation of the target library information.<br>
///<br>
-/// This both allows optimizations to handle them specially and frontends to<br>
-/// disable such optimizations through -fno-builtin etc.<br>
-class TargetLibraryInfo {<br>
+/// This class constructs tables that hold the target library information and<br>
+/// make it available. However, it is somewhat expensive to compute and only<br>
+/// depends on the triple. So users typicaly interact with the \c<br>
+/// TargetLibraryInfo wrapper below.<br>
+class TargetLibraryInfoImpl {<br>
+ friend class TargetLibraryInfo;<br>
+<br>
unsigned char AvailableArray[(LibFunc::NumLibFuncs+3)/4];<br>
llvm::DenseMap<unsigned, std::string> CustomNames;<br>
static const char* StandardNames[LibFunc::NumLibFuncs];<br>
@@ -720,14 +723,14 @@ class TargetLibraryInfo {<br>
}<br>
<br>
public:<br>
- TargetLibraryInfo();<br>
- explicit TargetLibraryInfo(const Triple &T);<br>
+ TargetLibraryInfoImpl();<br>
+ explicit TargetLibraryInfoImpl(const Triple &T);<br>
<br>
// Provide value semantics.<br>
- TargetLibraryInfo(const TargetLibraryInfo &TLI);<br>
- TargetLibraryInfo(TargetLibraryInfo &&TLI);<br>
- TargetLibraryInfo &operator=(const TargetLibraryInfo &TLI);<br>
- TargetLibraryInfo &operator=(TargetLibraryInfo &&TLI);<br>
+ TargetLibraryInfoImpl(const TargetLibraryInfoImpl &TLI);<br>
+ TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI);<br>
+ TargetLibraryInfoImpl &operator=(const TargetLibraryInfoImpl &TLI);<br>
+ TargetLibraryInfoImpl &operator=(TargetLibraryInfoImpl &&TLI);<br>
<br>
/// \brief Searches for a particular function name.<br>
///<br>
@@ -735,15 +738,77 @@ public:<br>
/// corresponding value.<br>
bool getLibFunc(StringRef funcName, LibFunc::Func &F) const;<br>
<br>
+ /// \brief Forces a function to be marked as unavailable.<br>
+ void setUnavailable(LibFunc::Func F) {<br>
+ setState(F, Unavailable);<br>
+ }<br>
+<br>
+ /// \brief Forces a function to be marked as available.<br>
+ void setAvailable(LibFunc::Func F) {<br>
+ setState(F, StandardName);<br>
+ }<br>
+<br>
+ /// \brief Forces a function to be marked as available and provide an<br>
+ /// alternate name that must be used.<br>
+ void setAvailableWithName(LibFunc::Func F, StringRef Name) {<br>
+ if (StandardNames[F] != Name) {<br>
+ setState(F, CustomName);<br>
+ CustomNames[F] = Name;<br>
+ assert(CustomNames.find(F) != CustomNames.end());<br>
+ } else {<br>
+ setState(F, StandardName);<br>
+ }<br>
+ }<br>
+<br>
+ /// \brief Disables all builtins.<br>
+ ///<br>
+ /// This can be used for options like -fno-builtin.<br>
+ void disableAllFunctions();<br>
+};<br>
+<br>
+/// \brief Provides information about what library functions are available for<br>
+/// the current target.<br>
+///<br>
+/// This both allows optimizations to handle them specially and frontends to<br>
+/// disable such optimizations through -fno-builtin etc.<br>
+class TargetLibraryInfo {<br>
+ friend class TargetLibraryAnalysis;<br>
+ friend class TargetLibraryInfoWrapperPass;<br>
+<br>
+ const TargetLibraryInfoImpl *Impl;<br>
+<br>
+public:<br>
+ explicit TargetLibraryInfo(const TargetLibraryInfoImpl &Impl) : Impl(&Impl) {}<br>
+<br>
+ // Provide value semantics.<br>
+ TargetLibraryInfo(const TargetLibraryInfo &TLI) : Impl(TLI.Impl) {}<br>
+ TargetLibraryInfo(TargetLibraryInfo &&TLI) : Impl(TLI.Impl) {}<br>
+ TargetLibraryInfo &operator=(const TargetLibraryInfo &TLI) {<br>
+ Impl = TLI.Impl;<br>
+ return *this;<br>
+ }<br>
+ TargetLibraryInfo &operator=(TargetLibraryInfo &&TLI) {<br>
+ Impl = TLI.Impl;<br>
+ return *this;<br>
+ }<br>
+<br>
+ /// \brief Searches for a particular function name.<br>
+ ///<br>
+ /// If it is one of the known library functions, return true and set F to the<br>
+ /// corresponding value.<br>
+ bool getLibFunc(StringRef funcName, LibFunc::Func &F) const {<br>
+ return Impl->getLibFunc(funcName, F);<br>
+ }<br>
+<br>
/// \brief Tests wether a library function is available.<br>
bool has(LibFunc::Func F) const {<br>
- return getState(F) != Unavailable;<br>
+ return Impl->getState(F) != TargetLibraryInfoImpl::Unavailable;<br>
}<br>
<br>
/// \brief Tests if the function is both available and a candidate for<br>
/// optimized code generation.<br>
bool hasOptimizedCodeGen(LibFunc::Func F) const {<br>
- if (getState(F) == Unavailable)<br>
+ if (Impl->getState(F) == TargetLibraryInfoImpl::Unavailable)<br>
return false;<br>
switch (F) {<br>
default: break;<br>
@@ -773,42 +838,15 @@ public:<br>
}<br>
<br>
StringRef getName(LibFunc::Func F) const {<br>
- AvailabilityState State = getState(F);<br>
- if (State == Unavailable)<br>
+ auto State = Impl->getState(F);<br>
+ if (State == TargetLibraryInfoImpl::Unavailable)<br>
return StringRef();<br>
- if (State == StandardName)<br>
- return StandardNames[F];<br>
- assert(State == CustomName);<br>
- return CustomNames.find(F)->second;<br>
+ if (State == TargetLibraryInfoImpl::StandardName)<br>
+ return Impl->StandardNames[F];<br>
+ assert(State == TargetLibraryInfoImpl::CustomName);<br>
+ return Impl->CustomNames.find(F)->second;<br>
}<br>
<br>
- /// \brief Forces a function to be marked as unavailable.<br>
- void setUnavailable(LibFunc::Func F) {<br>
- setState(F, Unavailable);<br>
- }<br>
-<br>
- /// \brief Forces a function to be marked as available.<br>
- void setAvailable(LibFunc::Func F) {<br>
- setState(F, StandardName);<br>
- }<br>
-<br>
- /// \brief Forces a function to be marked as available and provide an<br>
- /// alternate name that must be used.<br>
- void setAvailableWithName(LibFunc::Func F, StringRef Name) {<br>
- if (StandardNames[F] != Name) {<br>
- setState(F, CustomName);<br>
- CustomNames[F] = Name;<br>
- assert(CustomNames.find(F) != CustomNames.end());<br>
- } else {<br>
- setState(F, StandardName);<br>
- }<br>
- }<br>
-<br>
- /// \brief Disables all builtins.<br>
- ///<br>
- /// This can be used for options like -fno-builtin.<br>
- void disableAllFunctions();<br>
-<br>
/// \brief Handle invalidation from the pass manager.<br>
///<br>
/// If we try to invalidate this info, just return false. It cannot become<br>
@@ -837,29 +875,20 @@ public:<br>
///<br>
/// This will directly copy the preset info into the result without<br>
/// consulting the module's triple.<br>
- TargetLibraryAnalysis(TargetLibraryInfo PresetInfo)<br>
- : PresetInfo(std::move(PresetInfo)) {}<br>
+ TargetLibraryAnalysis(TargetLibraryInfoImpl PresetInfoImpl)<br>
+ : PresetInfoImpl(std::move(PresetInfoImpl)) {}<br>
<br>
- // Value semantics. We spell out the constructors for MSVC.<br>
- TargetLibraryAnalysis(const TargetLibraryAnalysis &Arg)<br>
- : PresetInfo(Arg.PresetInfo) {}<br>
+ // Move semantics. We spell out the constructors for MSVC.<br>
TargetLibraryAnalysis(TargetLibraryAnalysis &&Arg)<br>
- : PresetInfo(std::move(Arg.PresetInfo)) {}<br>
- TargetLibraryAnalysis &operator=(const TargetLibraryAnalysis &RHS) {<br>
- PresetInfo = RHS.PresetInfo;<br>
- return *this;<br>
- }<br>
+ : PresetInfoImpl(std::move(Arg.PresetInfoImpl)), Impls(std::move(Arg.Impls)) {}<br>
TargetLibraryAnalysis &operator=(TargetLibraryAnalysis &&RHS) {<br>
- PresetInfo = std::move(RHS.PresetInfo);<br>
+ PresetInfoImpl = std::move(RHS.PresetInfoImpl);<br>
+ Impls = std::move(RHS.Impls);<br>
return *this;<br>
}<br>
<br>
- TargetLibraryInfo run(Module &M) {<br>
- if (PresetInfo)<br>
- return *PresetInfo;<br>
-<br>
- return TargetLibraryInfo(Triple(M.getTargetTriple()));<br>
- }<br>
+ TargetLibraryInfo run(Module &M);<br>
+ TargetLibraryInfo run(Function &F);<br>
<br>
/// \brief Provide access to a name for this pass for debugging purposes.<br>
static StringRef name() { return "TargetLibraryAnalysis"; }<br>
@@ -867,10 +896,15 @@ public:<br>
private:<br>
static char PassID;<br>
<br>
- Optional<TargetLibraryInfo> PresetInfo;<br>
+ Optional<TargetLibraryInfoImpl> PresetInfoImpl;<br>
+<br>
+ StringMap<std::unique_ptr<TargetLibraryInfoImpl>> Impls;<br>
+<br>
+ TargetLibraryInfoImpl &lookupInfoImpl(Triple T);<br>
};<br>
<br>
class TargetLibraryInfoWrapperPass : public ImmutablePass {<br>
+ TargetLibraryInfoImpl TLIImpl;<br>
TargetLibraryInfo TLI;<br>
<br>
virtual void anchor();<br>
@@ -879,7 +913,7 @@ public:<br>
static char ID;<br>
TargetLibraryInfoWrapperPass();<br>
explicit TargetLibraryInfoWrapperPass(const Triple &T);<br>
- explicit TargetLibraryInfoWrapperPass(const TargetLibraryInfo &TLI);<br>
+ explicit TargetLibraryInfoWrapperPass(const TargetLibraryInfoImpl &TLI);<br>
<br>
TargetLibraryInfo &getTLI() { return TLI; }<br>
const TargetLibraryInfo &getTLI() const { return TLI; }<br>
<br>
Modified: llvm/trunk/include/llvm/Transforms/IPO/PassManagerBuilder.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/IPO/PassManagerBuilder.h?rev=226981&r1=226980&r2=226981&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/IPO/PassManagerBuilder.h?rev=226981&r1=226980&r2=226981&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/Transforms/IPO/PassManagerBuilder.h (original)<br>
+++ llvm/trunk/include/llvm/Transforms/IPO/PassManagerBuilder.h Fri Jan 23 20:06:09 2015<br>
@@ -19,7 +19,7 @@<br>
<br>
namespace llvm {<br>
class Pass;<br>
-class TargetLibraryInfo;<br>
+class TargetLibraryInfoImpl;<br>
class TargetMachine;<br>
<br>
// The old pass manager infrastructure is hidden in a legacy namespace now.<br>
@@ -105,7 +105,7 @@ public:<br>
/// LibraryInfo - Specifies information about the runtime library for the<br>
/// optimizer. If this is non-null, it is added to both the function and<br>
/// per-module pass pipeline.<br>
- TargetLibraryInfo *LibraryInfo;<br>
+ TargetLibraryInfoImpl *LibraryInfo;<br>
<br>
/// Inliner - Specifies the inliner to use. If this is non-null, it is<br>
/// added to the per-module passes.<br>
<br>
Modified: llvm/trunk/lib/Analysis/TargetLibraryInfo.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/TargetLibraryInfo.cpp?rev=226981&r1=226980&r2=226981&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/TargetLibraryInfo.cpp?rev=226981&r1=226980&r2=226981&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Analysis/TargetLibraryInfo.cpp (original)<br>
+++ llvm/trunk/lib/Analysis/TargetLibraryInfo.cpp Fri Jan 23 20:06:09 2015<br>
@@ -15,7 +15,7 @@<br>
#include "llvm/ADT/Triple.h"<br>
using namespace llvm;<br>
<br>
-const char* TargetLibraryInfo::StandardNames[LibFunc::NumLibFuncs] =<br>
+const char* TargetLibraryInfoImpl::StandardNames[LibFunc::NumLibFuncs] =<br>
{<br>
"_IO_getc",<br>
"_IO_putc",<br>
@@ -370,13 +370,13 @@ static bool hasSinCosPiStret(const Tripl<br>
/// initialize - Initialize the set of available library functions based on the<br>
/// specified target triple. This should be carefully written so that a missing<br>
/// target triple gets a sane set of defaults.<br>
-static void initialize(TargetLibraryInfo &TLI, const Triple &T,<br>
+static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T,<br>
const char **StandardNames) {<br>
#ifndef NDEBUG<br>
// Verify that the StandardNames array is in alphabetical order.<br>
for (unsigned F = 1; F < LibFunc::NumLibFuncs; ++F) {<br>
if (strcmp(StandardNames[F-1], StandardNames[F]) >= 0)<br>
- llvm_unreachable("TargetLibraryInfo function names must be sorted");<br>
+ llvm_unreachable("TargetLibraryInfoImpl function names must be sorted");<br>
}<br>
#endif // !NDEBUG<br>
<br>
@@ -676,38 +676,38 @@ static void initialize(TargetLibraryInfo<br>
}<br>
}<br>
<br>
-TargetLibraryInfo::TargetLibraryInfo() {<br>
+TargetLibraryInfoImpl::TargetLibraryInfoImpl() {<br>
// Default to everything being available.<br>
memset(AvailableArray, -1, sizeof(AvailableArray));<br>
<br>
initialize(*this, Triple(), StandardNames);<br>
}<br>
<br>
-TargetLibraryInfo::TargetLibraryInfo(const Triple &T) {<br>
+TargetLibraryInfoImpl::TargetLibraryInfoImpl(const Triple &T) {<br>
// Default to everything being available.<br>
memset(AvailableArray, -1, sizeof(AvailableArray));<br>
<br>
initialize(*this, T, StandardNames);<br>
}<br>
<br>
-TargetLibraryInfo::TargetLibraryInfo(const TargetLibraryInfo &TLI)<br>
+TargetLibraryInfoImpl::TargetLibraryInfoImpl(const TargetLibraryInfoImpl &TLI)<br>
: CustomNames(TLI.CustomNames) {<br>
memcpy(AvailableArray, TLI.AvailableArray, sizeof(AvailableArray));<br>
}<br>
<br>
-TargetLibraryInfo::TargetLibraryInfo(TargetLibraryInfo &&TLI)<br>
+TargetLibraryInfoImpl::TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI)<br>
: CustomNames(std::move(TLI.CustomNames)) {<br>
std::move(std::begin(TLI.AvailableArray), std::end(TLI.AvailableArray),<br>
AvailableArray);<br>
}<br>
<br>
-TargetLibraryInfo &TargetLibraryInfo::operator=(const TargetLibraryInfo &TLI) {<br>
+TargetLibraryInfoImpl &TargetLibraryInfoImpl::operator=(const TargetLibraryInfoImpl &TLI) {<br>
CustomNames = TLI.CustomNames;<br>
memcpy(AvailableArray, TLI.AvailableArray, sizeof(AvailableArray));<br>
return *this;<br>
}<br>
<br>
-TargetLibraryInfo &TargetLibraryInfo::operator=(TargetLibraryInfo &&TLI) {<br>
+TargetLibraryInfoImpl &TargetLibraryInfoImpl::operator=(TargetLibraryInfoImpl &&TLI) {<br>
CustomNames = std::move(TLI.CustomNames);<br>
std::move(std::begin(TLI.AvailableArray), std::end(TLI.AvailableArray),<br>
AvailableArray);<br>
@@ -733,7 +733,7 @@ struct StringComparator {<br>
};<br>
}<br>
<br>
-bool TargetLibraryInfo::getLibFunc(StringRef funcName,<br>
+bool TargetLibraryInfoImpl::getLibFunc(StringRef funcName,<br>
LibFunc::Func &F) const {<br>
const char **Start = &StandardNames[0];<br>
const char **End = &StandardNames[LibFunc::NumLibFuncs];<br>
@@ -755,23 +755,48 @@ bool TargetLibraryInfo::getLibFunc(Strin<br>
return false;<br>
}<br>
<br>
-void TargetLibraryInfo::disableAllFunctions() {<br>
+void TargetLibraryInfoImpl::disableAllFunctions() {<br>
memset(AvailableArray, 0, sizeof(AvailableArray));<br>
}<br>
<br>
+TargetLibraryInfo TargetLibraryAnalysis::run(Module &M) {<br>
+ if (PresetInfoImpl)<br>
+ return TargetLibraryInfo(*PresetInfoImpl);<br>
+<br>
+ return TargetLibraryInfo(lookupInfoImpl(Triple(M.getTargetTriple())));<br>
+}<br>
+<br>
+TargetLibraryInfo TargetLibraryAnalysis::run(Function &F) {<br>
+ if (PresetInfoImpl)<br>
+ return TargetLibraryInfo(*PresetInfoImpl);<br>
+<br>
+ return TargetLibraryInfo(<br>
+ lookupInfoImpl(Triple(F.getParent()->getTargetTriple())));<br>
+}<br>
+<br>
+TargetLibraryInfoImpl &TargetLibraryAnalysis::lookupInfoImpl(Triple T) {<br>
+ std::unique_ptr<TargetLibraryInfoImpl> &Impl =<br>
+ Impls[T.normalize()];<br>
+ if (!Impl)<br>
+ Impl.reset(new TargetLibraryInfoImpl(T));<br>
+<br>
+ return *Impl;<br>
+}<br>
+<br>
+<br>
TargetLibraryInfoWrapperPass::TargetLibraryInfoWrapperPass()<br>
- : ImmutablePass(ID), TLI() {<br>
+ : ImmutablePass(ID), TLIImpl(), TLI(TLIImpl) {<br>
initializeTargetLibraryInfoWrapperPassPass(*PassRegistry::getPassRegistry());<br>
}<br>
<br>
TargetLibraryInfoWrapperPass::TargetLibraryInfoWrapperPass(const Triple &T)<br>
- : ImmutablePass(ID), TLI(T) {<br>
+ : ImmutablePass(ID), TLIImpl(T), TLI(TLIImpl) {<br>
initializeTargetLibraryInfoWrapperPassPass(*PassRegistry::getPassRegistry());<br>
}<br>
<br>
TargetLibraryInfoWrapperPass::TargetLibraryInfoWrapperPass(<br>
- const TargetLibraryInfo &TLI)<br>
- : ImmutablePass(ID), TLI(TLI) {<br>
+ const TargetLibraryInfoImpl &TLIImpl)<br>
+ : ImmutablePass(ID), TLIImpl(TLIImpl), TLI(this->TLIImpl) {<br>
initializeTargetLibraryInfoWrapperPassPass(*PassRegistry::getPassRegistry());<br>
}<br>
<br>
<br>
Modified: llvm/trunk/lib/LTO/LTOCodeGenerator.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LTO/LTOCodeGenerator.cpp?rev=226981&r1=226980&r2=226981&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LTO/LTOCodeGenerator.cpp?rev=226981&r1=226980&r2=226981&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/LTO/LTOCodeGenerator.cpp (original)<br>
+++ llvm/trunk/lib/LTO/LTOCodeGenerator.cpp Fri Jan 23 20:06:09 2015<br>
@@ -410,7 +410,8 @@ void LTOCodeGenerator::applyScopeRestric<br>
std::vector<const char*> MustPreserveList;<br>
SmallPtrSet<GlobalValue*, 8> AsmUsed;<br>
std::vector<StringRef> Libcalls;<br>
- TargetLibraryInfo TLI(Triple(TargetMach->getTargetTriple()));<br>
+ TargetLibraryInfoImpl TLII(Triple(TargetMach->getTargetTriple()));<br>
+ TargetLibraryInfo TLI(TLII);<br>
accumulateAndSortLibcalls(<br>
Libcalls, TLI, TargetMach->getSubtargetImpl()->getTargetLowering());<br>
<br>
@@ -484,7 +485,7 @@ bool LTOCodeGenerator::generateObjectFil<br>
PMB.SLPVectorize = !DisableVectorization;<br>
if (!DisableInline)<br>
PMB.Inliner = createFunctionInliningPass();<br>
- PMB.LibraryInfo = new TargetLibraryInfo(TargetTriple);<br>
+ PMB.LibraryInfo = new TargetLibraryInfoImpl(TargetTriple);<br>
if (DisableOpt)<br>
PMB.OptLevel = 0;<br>
PMB.VerifyInput = true;<br>
<br>
Modified: llvm/trunk/lib/Target/Target.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Target.cpp?rev=226981&r1=226980&r2=226981&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Target.cpp?rev=226981&r1=226980&r2=226981&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/Target.cpp (original)<br>
+++ llvm/trunk/lib/Target/Target.cpp Fri Jan 23 20:06:09 2015<br>
@@ -24,12 +24,12 @@<br>
<br>
using namespace llvm;<br>
<br>
-inline TargetLibraryInfo *unwrap(LLVMTargetLibraryInfoRef P) {<br>
- return reinterpret_cast<TargetLibraryInfo*>(P);<br>
+inline TargetLibraryInfoImpl *unwrap(LLVMTargetLibraryInfoRef P) {<br>
+ return reinterpret_cast<TargetLibraryInfoImpl*>(P);<br>
}<br>
<br>
-inline LLVMTargetLibraryInfoRef wrap(const TargetLibraryInfo *P) {<br>
- TargetLibraryInfo *X = const_cast<TargetLibraryInfo*>(P);<br>
+inline LLVMTargetLibraryInfoRef wrap(const TargetLibraryInfoImpl *P) {<br>
+ TargetLibraryInfoImpl *X = const_cast<TargetLibraryInfoImpl*>(P);<br>
return reinterpret_cast<LLVMTargetLibraryInfoRef>(X);<br>
}<br>
<br>
<br>
Modified: llvm/trunk/tools/llc/llc.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llc/llc.cpp?rev=226981&r1=226980&r2=226981&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llc/llc.cpp?rev=226981&r1=226980&r2=226981&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/llc/llc.cpp (original)<br>
+++ llvm/trunk/tools/llc/llc.cpp Fri Jan 23 20:06:09 2015<br>
@@ -296,12 +296,12 @@ static int compileModule(char **argv, LL<br>
PassManager PM;<br>
<br>
// Add an appropriate TargetLibraryInfo pass for the module's triple.<br>
- TargetLibraryInfo TLI(Triple(M->getTargetTriple()));<br>
+ TargetLibraryInfoImpl TLII(Triple(M->getTargetTriple()));<br>
<br>
// The -disable-simplify-libcalls flag actually disables all builtin optzns.<br>
if (DisableSimplifyLibCalls)<br>
- TLI.disableAllFunctions();<br>
- PM.add(new TargetLibraryInfoWrapperPass(TLI));<br>
+ TLII.disableAllFunctions();<br>
+ PM.add(new TargetLibraryInfoWrapperPass(TLII));<br>
<br>
// Add the target data from the target machine, if it exists, or the module.<br>
if (const DataLayout *DL = Target->getSubtargetImpl()->getDataLayout())<br>
<br>
Modified: llvm/trunk/tools/opt/PassRegistry.def<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/opt/PassRegistry.def?rev=226981&r1=226980&r2=226981&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/opt/PassRegistry.def?rev=226981&r1=226980&r2=226981&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/opt/PassRegistry.def (original)<br>
+++ llvm/trunk/tools/opt/PassRegistry.def Fri Jan 23 20:06:09 2015<br>
@@ -54,6 +54,7 @@ FUNCTION_ANALYSIS("assumptions", Assumpt<br>
FUNCTION_ANALYSIS("domtree", DominatorTreeAnalysis())<br>
FUNCTION_ANALYSIS("loops", LoopAnalysis())<br>
FUNCTION_ANALYSIS("no-op-function", NoOpFunctionAnalysis())<br>
+FUNCTION_ANALYSIS("targetlibinfo", TargetLibraryAnalysis())<br>
#undef FUNCTION_ANALYSIS<br>
<br>
#ifndef FUNCTION_PASS<br>
<br>
Modified: llvm/trunk/tools/opt/opt.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/opt/opt.cpp?rev=226981&r1=226980&r2=226981&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/opt/opt.cpp?rev=226981&r1=226980&r2=226981&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/opt/opt.cpp (original)<br>
+++ llvm/trunk/tools/opt/opt.cpp Fri Jan 23 20:06:09 2015<br>
@@ -401,12 +401,12 @@ int main(int argc, char **argv) {<br>
PassManager Passes;<br>
<br>
// Add an appropriate TargetLibraryInfo pass for the module's triple.<br>
- TargetLibraryInfo TLI(Triple(M->getTargetTriple()));<br>
+ TargetLibraryInfoImpl TLII(Triple(M->getTargetTriple()));<br>
<br>
// The -disable-simplify-libcalls flag actually disables all builtin optzns.<br>
if (DisableSimplifyLibCalls)<br>
- TLI.disableAllFunctions();<br>
- Passes.add(new TargetLibraryInfoWrapperPass(TLI));<br>
+ TLII.disableAllFunctions();<br>
+ Passes.add(new TargetLibraryInfoWrapperPass(TLII));<br>
<br>
// Add an appropriate DataLayout instance for this module.<br>
const DataLayout *DL = M->getDataLayout();<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div></div>