diff options
| author | Daniel Dunbar <daniel@zuster.org> | 2009-07-15 04:24:58 +0000 | 
|---|---|---|
| committer | Daniel Dunbar <daniel@zuster.org> | 2009-07-15 04:24:58 +0000 | 
| commit | 078a71e4a92970a66b96959d35b6479032e220cc (patch) | |
| tree | 9472256d7ffcae386bf46e4307e9393502d24b5c /llvm/lib/Support | |
| parent | 57fa7e3cc8d84ca20fa569208207e90e3bfc6b6a (diff) | |
| download | bcm5719-llvm-078a71e4a92970a66b96959d35b6479032e220cc.tar.gz bcm5719-llvm-078a71e4a92970a66b96959d35b6479032e220cc.zip | |
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.
llvm-svn: 75739
Diffstat (limited to 'llvm/lib/Support')
| -rw-r--r-- | llvm/lib/Support/TargetRegistry.cpp | 136 | 
1 files changed, 136 insertions, 0 deletions
| diff --git a/llvm/lib/Support/TargetRegistry.cpp b/llvm/lib/Support/TargetRegistry.cpp new file mode 100644 index 00000000000..24f87ce6821 --- /dev/null +++ b/llvm/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; +} + | 

