[llvm] r227721 - [PM] Port TTI to the new pass manager, introducing a TargetIRAnalysis to

Chandler Carruth chandlerc at gmail.com
Sun Feb 1 02:11:23 PST 2015


Author: chandlerc
Date: Sun Feb  1 04:11:22 2015
New Revision: 227721

URL: http://llvm.org/viewvc/llvm-project?rev=227721&view=rev
Log:
[PM] Port TTI to the new pass manager, introducing a TargetIRAnalysis to
produce it.

This adds a function to the TargetMachine that produces this analysis
via a callback for each function. This in turn faves the way to produce
a *different* TTI per-function with the correct subtarget cached.

I've also done the necessary wiring in the opt tool to thread the target
machine down and make it available to the pass registry so that we can
construct this analysis from a target machine when available.

Modified:
    llvm/trunk/include/llvm/Analysis/TargetTransformInfo.h
    llvm/trunk/include/llvm/Target/TargetMachine.h
    llvm/trunk/lib/Analysis/TargetTransformInfo.cpp
    llvm/trunk/lib/Target/TargetMachine.cpp
    llvm/trunk/test/Other/new-pass-manager.ll
    llvm/trunk/tools/opt/NewPMDriver.cpp
    llvm/trunk/tools/opt/NewPMDriver.h
    llvm/trunk/tools/opt/PassRegistry.def
    llvm/trunk/tools/opt/Passes.cpp
    llvm/trunk/tools/opt/Passes.h
    llvm/trunk/tools/opt/opt.cpp

Modified: llvm/trunk/include/llvm/Analysis/TargetTransformInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/TargetTransformInfo.h?rev=227721&r1=227720&r2=227721&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/TargetTransformInfo.h (original)
+++ llvm/trunk/include/llvm/Analysis/TargetTransformInfo.h Sun Feb  1 04:11:22 2015
@@ -32,6 +32,7 @@ namespace llvm {
 class Function;
 class GlobalValue;
 class Loop;
+class PreservedAnalyses;
 class Type;
 class User;
 class Value;
@@ -76,6 +77,17 @@ public:
   // out-of-line.
   ~TargetTransformInfo();
 
+  /// \brief Handle the invalidation of this information.
+  ///
+  /// When used as a result of \c TargetIRAnalysis this method will be called
+  /// when the function this was computed for changes. When it returns false,
+  /// the information is preserved across those changes.
+  bool invalidate(Function &, const PreservedAnalyses &) {
+    // FIXME: We should probably in some way ensure that the subtarget
+    // information for a function hasn't changed.
+    return false;
+  }
+
   /// \name Generic Target Information
   /// @{
 
@@ -706,6 +718,74 @@ template <typename T>
 TargetTransformInfo::TargetTransformInfo(T Impl)
     : TTIImpl(new Model<T>(Impl)) {}
 
+/// \brief Analysis pass providing the \c TargetTransformInfo.
+///
+/// The core idea of the TargetIRAnalysis is to expose an interface through
+/// which LLVM targets can analyze and provide information about the middle
+/// end's target-independent IR. This supports use cases such as target-aware
+/// cost modeling of IR constructs.
+///
+/// This is a function analysis because much of the cost modeling for targets
+/// is done in a subtarget specific way and LLVM supports compiling different
+/// functions targeting different subtargets in order to support runtime
+/// dispatch according to the observed subtarget.
+class TargetIRAnalysis {
+public:
+  typedef TargetTransformInfo Result;
+
+  /// \brief Opaque, unique identifier for this analysis pass.
+  static void *ID() { return (void *)&PassID; }
+
+  /// \brief Provide access to a name for this pass for debugging purposes.
+  static StringRef name() { return "TargetIRAnalysis"; }
+
+  /// \brief Default construct a target IR analysis.
+  ///
+  /// This will use the module's datalayout to construct a baseline
+  /// conservative TTI result.
+  TargetIRAnalysis();
+
+  /// \brief Construct an IR analysis pass around a target-provide callback.
+  ///
+  /// The callback will be called with a particular function for which the TTI
+  /// is needed and must return a TTI object for that function.
+  TargetIRAnalysis(std::function<Result(Function &)> TTICallback);
+
+  // Value semantics. We spell out the constructors for MSVC.
+  TargetIRAnalysis(const TargetIRAnalysis &Arg)
+      : TTICallback(Arg.TTICallback) {}
+  TargetIRAnalysis(TargetIRAnalysis &&Arg)
+      : TTICallback(std::move(Arg.TTICallback)) {}
+  TargetIRAnalysis &operator=(const TargetIRAnalysis &RHS) {
+    TTICallback = RHS.TTICallback;
+    return *this;
+  }
+  TargetIRAnalysis &operator=(TargetIRAnalysis &&RHS) {
+    TTICallback = std::move(RHS.TTICallback);
+    return *this;
+  }
+
+  Result run(Function &F);
+
+private:
+  static char PassID;
+
+  /// \brief The callback used to produce a result.
+  ///
+  /// We use a completely opaque callback so that targets can provide whatever
+  /// mechanism they desire for constructing the TTI for a given function.
+  ///
+  /// FIXME: Should we really use std::function? It's relatively inefficient.
+  /// It might be possible to arrange for even stateful callbacks to outlive
+  /// the analysis and thus use a function_ref which would be lighter weight.
+  /// This may also be less error prone as the callback is likely to reference
+  /// the external TargetMachine, and that reference needs to never dangle.
+  std::function<Result(Function &)> TTICallback;
+
+  /// \brief Helper function used as the callback in the default constructor.
+  static Result getDefaultTTI(Function &F);
+};
+
 /// \brief Wrapper pass for TargetTransformInfo.
 ///
 /// This pass can be constructed from a TTI object which it stores internally

Modified: llvm/trunk/include/llvm/Target/TargetMachine.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetMachine.h?rev=227721&r1=227720&r2=227721&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetMachine.h (original)
+++ llvm/trunk/include/llvm/Target/TargetMachine.h Sun Feb  1 04:11:22 2015
@@ -34,6 +34,7 @@ class Target;
 class DataLayout;
 class TargetLibraryInfo;
 class TargetFrameLowering;
+class TargetIRAnalysis;
 class TargetIntrinsicInfo;
 class TargetLowering;
 class TargetPassConfig;
@@ -187,6 +188,12 @@ public:
   /// sections.
   void setFunctionSections(bool);
 
+  /// \brief Get a \c TargetIRAnalysis appropriate for the target.
+  ///
+  /// This is used to construct the new pass manager's target IR analysis pass,
+  /// set up appropriately for this target machine.
+  virtual TargetIRAnalysis getTargetIRAnalysis();
+
   /// \brief Get a TTI implementation for the target.
   ///
   /// Targets should override this method to provide target-accurate

Modified: llvm/trunk/lib/Analysis/TargetTransformInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/TargetTransformInfo.cpp?rev=227721&r1=227720&r2=227721&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/TargetTransformInfo.cpp (original)
+++ llvm/trunk/lib/Analysis/TargetTransformInfo.cpp Sun Feb  1 04:11:22 2015
@@ -14,6 +14,7 @@
 #include "llvm/IR/Instruction.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
 #include "llvm/IR/Operator.h"
 #include "llvm/Support/ErrorHandling.h"
 
@@ -255,6 +256,22 @@ Value *TargetTransformInfo::getOrCreateR
 
 TargetTransformInfo::Concept::~Concept() {}
 
+TargetIRAnalysis::TargetIRAnalysis() : TTICallback(&getDefaultTTI) {}
+
+TargetIRAnalysis::TargetIRAnalysis(
+    std::function<Result(Function &)> TTICallback)
+    : TTICallback(TTICallback) {}
+
+TargetIRAnalysis::Result TargetIRAnalysis::run(Function &F) {
+  return TTICallback(F);
+}
+
+char TargetIRAnalysis::PassID;
+
+TargetIRAnalysis::Result TargetIRAnalysis::getDefaultTTI(Function &F) {
+  return Result(F.getParent()->getDataLayout());
+}
+
 // Register the basic pass.
 INITIALIZE_PASS(TargetTransformInfoWrapperPass, "tti",
                 "Target Transform Information", false, true)

Modified: llvm/trunk/lib/Target/TargetMachine.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetMachine.cpp?rev=227721&r1=227720&r2=227721&view=diff
==============================================================================
--- llvm/trunk/lib/Target/TargetMachine.cpp (original)
+++ llvm/trunk/lib/Target/TargetMachine.cpp Sun Feb  1 04:11:22 2015
@@ -172,6 +172,13 @@ void TargetMachine::setDataSections(bool
   Options.DataSections = V;
 }
 
+TargetIRAnalysis TargetMachine::getTargetIRAnalysis() {
+  // While targets are free to just override getTTI and rely on this analysis,
+  // it would be more efficient to override and provide an analysis that could
+  // directly construct that target's TTI without the virtual call.
+  return TargetIRAnalysis([this](Function &) { return getTTI(); });
+}
+
 TargetTransformInfo TargetMachine::getTTI() {
   return TargetTransformInfo(getDataLayout());
 }

Modified: llvm/trunk/test/Other/new-pass-manager.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/new-pass-manager.ll?rev=227721&r1=227720&r2=227721&view=diff
==============================================================================
--- llvm/trunk/test/Other/new-pass-manager.ll (original)
+++ llvm/trunk/test/Other/new-pass-manager.ll Sun Feb  1 04:11:22 2015
@@ -278,6 +278,18 @@
 ; CHECK-TLI-NOT: Running analysis: TargetLibraryAnalysis
 ; CHECK-TLI: Finished pass manager
 
+; RUN: opt -disable-output -disable-verify -debug-pass-manager %s 2>&1 \
+; RUN:     -passes='require<targetir>,invalidate<all>,require<targetir>' \
+; RUN:     | FileCheck %s --check-prefix=CHECK-TIRA
+; CHECK-TIRA: Starting pass manager
+; CHECK-TIRA: Running pass: RequireAnalysisPass
+; CHECK-TIRA: Running analysis: TargetIRAnalysis
+; CHECK-TIRA: Running pass: InvalidateAllAnalysesPass
+; CHECK-TIRA-NOT: Invalidating analysis: TargetIRAnalysis
+; CHECK-TIRA: Running pass: RequireAnalysisPass
+; CHECK-TIRA-NOT: Running analysis: TargetIRAnalysis
+; CHECK-TIRA: Finished pass manager
+
 define void @foo() {
   ret void
 }

Modified: llvm/trunk/tools/opt/NewPMDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/opt/NewPMDriver.cpp?rev=227721&r1=227720&r2=227721&view=diff
==============================================================================
--- llvm/trunk/tools/opt/NewPMDriver.cpp (original)
+++ llvm/trunk/tools/opt/NewPMDriver.cpp Sun Feb  1 04:11:22 2015
@@ -27,6 +27,7 @@
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Target/TargetMachine.h"
 
 using namespace llvm;
 using namespace opt_tool;
@@ -36,9 +37,10 @@ static cl::opt<bool>
             cl::desc("Print pass management debugging information"));
 
 bool llvm::runPassPipeline(StringRef Arg0, LLVMContext &Context, Module &M,
-                           tool_output_file *Out, StringRef PassPipeline,
-                           OutputKind OK, VerifierKind VK) {
-  Passes P;
+                           TargetMachine *TM, tool_output_file *Out,
+                           StringRef PassPipeline, OutputKind OK,
+                           VerifierKind VK) {
+  Passes P(TM);
 
   FunctionAnalysisManager FAM(DebugPM);
   CGSCCAnalysisManager CGAM(DebugPM);

Modified: llvm/trunk/tools/opt/NewPMDriver.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/opt/NewPMDriver.h?rev=227721&r1=227720&r2=227721&view=diff
==============================================================================
--- llvm/trunk/tools/opt/NewPMDriver.h (original)
+++ llvm/trunk/tools/opt/NewPMDriver.h Sun Feb  1 04:11:22 2015
@@ -26,6 +26,7 @@
 namespace llvm {
 class LLVMContext;
 class Module;
+class TargetMachine;
 class tool_output_file;
 
 namespace opt_tool {
@@ -48,8 +49,9 @@ enum VerifierKind {
 /// file. It's interface is consequentially somewhat ad-hoc, but will go away
 /// when the transition finishes.
 bool runPassPipeline(StringRef Arg0, LLVMContext &Context, Module &M,
-                     tool_output_file *Out, StringRef PassPipeline,
-                     opt_tool::OutputKind OK, opt_tool::VerifierKind VK);
+                     TargetMachine *TM, tool_output_file *Out,
+                     StringRef PassPipeline, opt_tool::OutputKind OK,
+                     opt_tool::VerifierKind VK);
 }
 
 #endif

Modified: llvm/trunk/tools/opt/PassRegistry.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/opt/PassRegistry.def?rev=227721&r1=227720&r2=227721&view=diff
==============================================================================
--- llvm/trunk/tools/opt/PassRegistry.def (original)
+++ llvm/trunk/tools/opt/PassRegistry.def Sun Feb  1 04:11:22 2015
@@ -55,6 +55,8 @@ FUNCTION_ANALYSIS("domtree", DominatorTr
 FUNCTION_ANALYSIS("loops", LoopAnalysis())
 FUNCTION_ANALYSIS("no-op-function", NoOpFunctionAnalysis())
 FUNCTION_ANALYSIS("targetlibinfo", TargetLibraryAnalysis())
+FUNCTION_ANALYSIS("targetir",
+                  TM ? TM->getTargetIRAnalysis() : TargetIRAnalysis())
 #undef FUNCTION_ANALYSIS
 
 #ifndef FUNCTION_PASS

Modified: llvm/trunk/tools/opt/Passes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/opt/Passes.cpp?rev=227721&r1=227720&r2=227721&view=diff
==============================================================================
--- llvm/trunk/tools/opt/Passes.cpp (original)
+++ llvm/trunk/tools/opt/Passes.cpp Sun Feb  1 04:11:22 2015
@@ -20,11 +20,13 @@
 #include "llvm/Analysis/LazyCallGraph.h"
 #include "llvm/Analysis/LoopInfo.h"
 #include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
 #include "llvm/IR/Dominators.h"
 #include "llvm/IR/IRPrintingPasses.h"
 #include "llvm/IR/PassManager.h"
 #include "llvm/IR/Verifier.h"
 #include "llvm/Support/Debug.h"
+#include "llvm/Target/TargetMachine.h"
 #include "llvm/Transforms/InstCombine/InstCombine.h"
 #include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h"
 

Modified: llvm/trunk/tools/opt/Passes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/opt/Passes.h?rev=227721&r1=227720&r2=227721&view=diff
==============================================================================
--- llvm/trunk/tools/opt/Passes.h (original)
+++ llvm/trunk/tools/opt/Passes.h Sun Feb  1 04:11:22 2015
@@ -21,6 +21,7 @@
 #include "llvm/IR/PassManager.h"
 
 namespace llvm {
+class TargetMachine;
 
 /// \brief This class provides access to all of LLVM's passes.
 ///
@@ -29,7 +30,11 @@ namespace llvm {
 /// of the built-in passes, and those may reference these members during
 /// construction.
 class Passes {
+  TargetMachine *TM;
+
 public:
+  explicit Passes(TargetMachine *TM = nullptr) : TM(TM) {}
+
   /// \brief Registers all available module analysis passes.
   ///
   /// This is an interface that can be used to populate a \c

Modified: llvm/trunk/tools/opt/opt.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/opt/opt.cpp?rev=227721&r1=227720&r2=227721&view=diff
==============================================================================
--- llvm/trunk/tools/opt/opt.cpp (original)
+++ llvm/trunk/tools/opt/opt.cpp Sun Feb  1 04:11:22 2015
@@ -370,6 +370,12 @@ int main(int argc, char **argv) {
     }
   }
 
+  Triple ModuleTriple(M->getTargetTriple());
+  TargetMachine *Machine = nullptr;
+  if (ModuleTriple.getArch())
+    Machine = GetTargetMachine(ModuleTriple);
+  std::unique_ptr<TargetMachine> TM(Machine);
+
   // If the output is set to be emitted to standard out, and standard out is a
   // console, print out a warning message and refuse to do it.  We don't
   // impress anyone by spewing tons of binary goo to a terminal.
@@ -391,8 +397,8 @@ int main(int argc, char **argv) {
     // The user has asked to use the new pass manager and provided a pipeline
     // string. Hand off the rest of the functionality to the new code for that
     // layer.
-    return runPassPipeline(argv[0], Context, *M, Out.get(), PassPipeline,
-                           OK, VK)
+    return runPassPipeline(argv[0], Context, *M, TM.get(), Out.get(),
+                           PassPipeline, OK, VK)
                ? 0
                : 1;
   }
@@ -403,7 +409,7 @@ int main(int argc, char **argv) {
   PassManager Passes;
 
   // Add an appropriate TargetLibraryInfo pass for the module's triple.
-  TargetLibraryInfoImpl TLII(Triple(M->getTargetTriple()));
+  TargetLibraryInfoImpl TLII(ModuleTriple);
 
   // The -disable-simplify-libcalls flag actually disables all builtin optzns.
   if (DisableSimplifyLibCalls)
@@ -420,12 +426,6 @@ int main(int argc, char **argv) {
   if (DL)
     Passes.add(new DataLayoutPass());
 
-  Triple ModuleTriple(M->getTargetTriple());
-  TargetMachine *Machine = nullptr;
-  if (ModuleTriple.getArch())
-    Machine = GetTargetMachine(Triple(ModuleTriple));
-  std::unique_ptr<TargetMachine> TM(Machine);
-
   // Add internal analysis passes from the target machine.
   Passes.add(createTargetTransformInfoWrapperPass(
       TM ? TM->getTTI() : TargetTransformInfo(DL)));





More information about the llvm-commits mailing list