[llvm-commits] [llvm] r75739 - in /llvm/trunk: include/llvm/Target/TargetRegistry.h lib/Support/TargetRegistry.cpp

Daniel Dunbar daniel at zuster.org
Tue Jul 14 21:25:00 PDT 2009


Author: ddunbar
Date: Tue Jul 14 23:24:58 2009
New Revision: 75739

URL: http://llvm.org/viewvc/llvm-project?rev=75739&view=rev
Log:
Add new TargetRegistry.

Targets implement a single global Target structure which will live in a new
<Target>/TargetInfo library; this will be present in any image which the target
is usable in.
 - Optional target specific classes can then be registered and attached to the
   Target description.

 - Registration for normal Targets will be done via the initialization functions
   instead of using static constructors.

 - This allows clients to use a single interface to obtain target data, without
   requiring the code generator be linked in. It also provides a natural
   extension point for adding new optional target data (assembler parser,
   disassembler, etc.).

 - This also provides a new entry point for obtaining a target for a particular
   triple (without a module).

 - Not yet used, however this should eventually replace the TargetMachineRegistry.

Added:
    llvm/trunk/include/llvm/Target/TargetRegistry.h
    llvm/trunk/lib/Support/TargetRegistry.cpp

Added: llvm/trunk/include/llvm/Target/TargetRegistry.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetRegistry.h?rev=75739&view=auto

==============================================================================
--- llvm/trunk/include/llvm/Target/TargetRegistry.h (added)
+++ llvm/trunk/include/llvm/Target/TargetRegistry.h Tue Jul 14 23:24:58 2009
@@ -0,0 +1,179 @@
+//===-- Target/TargetRegistry.h - Target Registration -----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file exposes the TargetRegistry interface, which tools can use to access
+// the appropriate target specific classes (TargetMachine, AsmPrinter, etc.)
+// which have been registered.
+//
+// Target specific class implementations should register themselves using the
+// appropriate TargetRegistry interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETREGISTRY_H
+#define LLVM_TARGET_TARGETREGISTRY_H
+
+#include <string>
+#include <cassert>
+
+namespace llvm {
+  class FunctionPass;
+  class Module;
+  class TargetMachine;
+  class formatted_raw_ostream;
+
+  /// Target - Wrapper for Target specific information.
+  ///
+  /// For registration purposes, this is a POD type so that targets can be
+  /// registered without the use of static constructors.
+  struct Target {
+  private:
+    typedef unsigned (*TripleMatchQualityFnTy)(const std::string &TT);
+    typedef unsigned (*ModuleMatchQualityFnTy)(const Module &M);
+    typedef unsigned (*JITMatchQualityFnTy)();
+
+    typedef TargetMachine *(*TargetMachineCtorTy)(const Module &, 
+                                                  const std::string &);
+    typedef FunctionPass *(*AsmPrinterCtorTy)(formatted_raw_ostream &,
+                                              TargetMachine &,
+                                              bool);
+
+    friend class TargetRegistry;
+
+    /// Next - The next registered target in the linked list, maintained by the
+    /// TargetRegistry.
+    Target *Next;
+
+    /// TripleMatchQualityFn - The target function for rating the match quality
+    /// of a triple.
+    TripleMatchQualityFnTy TripleMatchQualityFn;
+
+    /// ModuleMatchQualityFn - The target function for rating the match quality
+    /// of a module.
+    ModuleMatchQualityFnTy ModuleMatchQualityFn;
+
+    /// JITMatchQualityFn - The target function for rating the match quality
+    /// with the host.
+    JITMatchQualityFnTy JITMatchQualityFn;
+
+    /// Name - The target name.
+    const char *Name;
+
+    /// ShortDesc - A short description of the target.
+    const char *ShortDesc;
+
+    /// TargetMachineCtorFn - Construction function for this target's
+    /// TargetMachine, if registered.
+    TargetMachineCtorTy TargetMachineCtorFn;
+
+    /// AsmPrinterCtorFn - Construction function for this target's AsmPrinter,
+    /// if registered.
+    AsmPrinterCtorTy AsmPrinterCtorFn;
+
+  public:
+    /// getName - Get the target name.
+    const char *getName() const { return Name; }
+
+    /// getShortDescription - Get a short description of the target.
+    const char *getShortDescription() const { return ShortDesc; }
+
+    /// createTargetMachine - Create a target specific machine implementation.
+    TargetMachine *createTargetMachine(const Module &M,
+                                       const std::string &Features) {
+      if (!TargetMachineCtorFn)
+        return 0;
+      return TargetMachineCtorFn(M, Features);
+    }
+
+    /// createAsmPrinter - Create a target specific assembly printer pass.
+    FunctionPass *createAsmPrinter(formatted_raw_ostream &OS,
+                                   TargetMachine &M,
+                                   bool Verbose) {
+      if (!AsmPrinterCtorFn)
+        return 0;
+      return AsmPrinterCtorFn(OS, M, Verbose);
+    }
+  };
+
+  /// TargetRegistry - Generic interface to target specific features.
+  //
+  // FIXME: Provide Target* iterator.
+  struct TargetRegistry {
+    /// @name Registry Access
+    /// @{
+
+    /// getClosestStaticTargetForTriple - Given a target triple, pick the most
+    /// capable target for that triple.
+    static const Target *getClosestStaticTargetForTriple(const std::string &TT,
+                                                         std::string &Error);
+
+    /// getClosestStaticTargetForModule - Given an LLVM module, pick the best
+    /// target that is compatible with the module.  If no close target can be
+    /// found, this returns null and sets the Error string to a reason.
+    static const Target *getClosestStaticTargetForModule(const Module &M,
+                                                        std::string &Error);
+
+    /// getClosestTargetForJIT - Pick the best target that is compatible with
+    /// the current host.  If no close target can be found, this returns null
+    /// and sets the Error string to a reason.
+    //
+    // FIXME: Do we still need this interface, clients can always look for the
+    // match for the host triple.
+    static const Target *getClosestTargetForJIT(std::string &Error);
+
+    /// @}
+    /// @name Target Registration
+    /// @{
+
+    /// RegisterTarget - Register the given target.
+    ///
+    /// @param T - The target being registered.
+    /// @param Name - The target name. This should be a static string.
+    /// @param ShortDesc - A short target description. This should be a static
+    /// string. 
+    /// @param TQualityFn - The triple match quality computation function for
+    /// this target.
+    /// @param MQualityFn - The module match quality computation function for
+    /// this target.
+    /// @param JITMatchQualityFn - The JIT match quality computation function
+    /// for this target.
+    static void RegisterTarget(Target &T,
+                               const char *Name,
+                               const char *ShortDesc,
+                               Target::TripleMatchQualityFnTy TQualityFn,
+                               Target::ModuleMatchQualityFnTy MQualityFn,
+                               Target::JITMatchQualityFnTy JITQualityFn);
+                               
+    /// RegisterTargetMachine - Register a TargetMachine implementation for the
+    /// given target.
+    /// 
+    /// @param T - The target being registered.
+    /// @param Fn - A function to construct a TargetMachine for the target.
+    static void RegisterTargetMachine(Target &T, 
+                                      Target::TargetMachineCtorTy Fn) {
+      assert(!T.TargetMachineCtorFn && "Constructor already registered!");
+      T.TargetMachineCtorFn = Fn;
+    }
+
+    /// RegisterAsmPrinter - Register an AsmPrinter implementation for the given
+    /// target.
+    /// 
+    /// @param T - The target being registered.
+    /// @param Fn - A function to construct an AsmPrinter for the target.
+    static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn) {
+      assert(!T.TargetMachineCtorFn && "Constructor already registered!");
+      T.AsmPrinterCtorFn = Fn;
+    }
+
+    /// @}
+  };
+
+}
+
+#endif

Added: llvm/trunk/lib/Support/TargetRegistry.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/TargetRegistry.cpp?rev=75739&view=auto

==============================================================================
--- llvm/trunk/lib/Support/TargetRegistry.cpp (added)
+++ llvm/trunk/lib/Support/TargetRegistry.cpp Tue Jul 14 23:24:58 2009
@@ -0,0 +1,136 @@
+//===--- TargetRegistry.cpp - Target registration -------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Target/TargetRegistry.h"
+#include <cassert>
+using namespace llvm;
+
+// FIXME: Worry about locking? In general everything should be registered at
+// startup.
+
+static Target *FirstTarget = 0;
+
+const Target *
+TargetRegistry::getClosestStaticTargetForTriple(const std::string &TT,
+                                                std::string &Error) {
+  Target *Best = 0, *EquallyBest = 0;
+  unsigned BestQuality = 0;
+  // FIXME: Use iterator.
+  for (Target *i = FirstTarget; i; i = i->Next) {
+    if (unsigned Qual = i->TripleMatchQualityFn(TT)) {
+      if (!Best || Qual > BestQuality) {
+        Best = i;
+        EquallyBest = 0;
+        BestQuality = Qual;
+      } else if (Qual == BestQuality)
+        EquallyBest = i;
+    }
+  }
+
+  if (!Best) {
+    Error = "No available targets are compatible with this module";
+    return 0;
+  }
+
+  // Otherwise, take the best target, but make sure we don't have two equally
+  // good best targets.
+  if (EquallyBest) {
+    Error = std::string("Cannot choose between targets \"") +
+      Best->Name  + "\" and \"" + EquallyBest->Name + "\"";
+    return 0;
+  }
+
+  return Best;
+}
+
+const Target *
+TargetRegistry::getClosestStaticTargetForModule(const Module &M,
+                                                std::string &Error) {
+  Target *Best = 0, *EquallyBest = 0;
+  unsigned BestQuality = 0;
+  // FIXME: Use iterator.
+  for (Target *i = FirstTarget; i; i = i->Next) {
+    if (unsigned Qual = i->ModuleMatchQualityFn(M)) {
+      if (!Best || Qual > BestQuality) {
+        Best = i;
+        EquallyBest = 0;
+        BestQuality = Qual;
+      } else if (Qual == BestQuality)
+        EquallyBest = i;
+    }
+  }
+
+  if (!Best) {
+    Error = "No available targets are compatible with this module";
+    return 0;
+  }
+
+  // Otherwise, take the best target, but make sure we don't have two equally
+  // good best targets.
+  if (EquallyBest) {
+    Error = std::string("Cannot choose between targets \"") +
+      Best->Name  + "\" and \"" + EquallyBest->Name + "\"";
+    return 0;
+  }
+
+  return Best;
+}
+
+const Target *
+TargetRegistry::getClosestTargetForJIT(std::string &Error) {
+  Target *Best = 0, *EquallyBest = 0;
+  unsigned BestQuality = 0;
+  // FIXME: Use iterator.
+  for (Target *i = FirstTarget; i; i = i->Next) {
+    if (unsigned Qual = i->JITMatchQualityFn()) {
+      if (!Best || Qual > BestQuality) {
+        Best = i;
+        EquallyBest = 0;
+        BestQuality = Qual;
+      } else if (Qual == BestQuality)
+        EquallyBest = i;
+    }
+  }
+
+  if (!Best) {
+    Error = "No JIT is available for this host";
+    return 0;
+  }
+
+  // Return the best, ignoring ties.
+  return Best;
+}
+
+void TargetRegistry::RegisterTarget(Target &T,
+                                    const char *Name,
+                                    const char *ShortDesc,
+                                    Target::TripleMatchQualityFnTy TQualityFn,
+                                    Target::ModuleMatchQualityFnTy MQualityFn,
+                                    Target::JITMatchQualityFnTy JITQualityFn) {
+  // Note that we don't require the constructor functions already be defined, in
+  // case a module happens to initialize the optional functionality before the
+  // target.
+  assert(!T.Next && !T.Name && !T.ShortDesc && !T.TripleMatchQualityFn &&
+         !T.ModuleMatchQualityFn && !T.JITMatchQualityFn && 
+         "This Target already registered!");
+
+  assert(Name && ShortDesc && TQualityFn && MQualityFn && JITQualityFn &&
+         "Missing required target information!");
+         
+  // Add to the list of targets.
+  T.Next = FirstTarget;
+  FirstTarget = T.Next;
+
+  T.Name = Name;
+  T.ShortDesc = ShortDesc;
+  T.TripleMatchQualityFn = TQualityFn;
+  T.ModuleMatchQualityFn = MQualityFn;
+  T.JITMatchQualityFn = JITQualityFn;
+}
+





More information about the llvm-commits mailing list