aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-07-15 04:24:58 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-07-15 04:24:58 +0000
commitbb061291406b1b9f0c976e9845f69f9faf985606 (patch)
tree9cd372ba4d91849ff6d1217b8bb9dd4eec4de40a
parent4fb63d088bca9fc31e54eb1619e2cb448c3a4b53 (diff)
downloadexternal_llvm-bb061291406b1b9f0c976e9845f69f9faf985606.zip
external_llvm-bb061291406b1b9f0c976e9845f69f9faf985606.tar.gz
external_llvm-bb061291406b1b9f0c976e9845f69f9faf985606.tar.bz2
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75739 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/Target/TargetRegistry.h179
-rw-r--r--lib/Support/TargetRegistry.cpp136
2 files changed, 315 insertions, 0 deletions
diff --git a/include/llvm/Target/TargetRegistry.h b/include/llvm/Target/TargetRegistry.h
new file mode 100644
index 0000000..ce1b281
--- /dev/null
+++ b/include/llvm/Target/TargetRegistry.h
@@ -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
diff --git a/lib/Support/TargetRegistry.cpp b/lib/Support/TargetRegistry.cpp
new file mode 100644
index 0000000..24f87ce
--- /dev/null
+++ b/lib/Support/TargetRegistry.cpp
@@ -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;
+}
+