<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>