LCOV - code coverage report
Current view: top level - lib/Support - TargetRegistry.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 41 61 67.2 %
Date: 2017-09-14 15:23:50 Functions: 4 6 66.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===--- TargetRegistry.cpp - Target registration -------------------------===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : 
      10             : #include "llvm/Support/TargetRegistry.h"
      11             : #include "llvm/ADT/STLExtras.h"
      12             : #include "llvm/ADT/StringRef.h"
      13             : #include "llvm/Support/raw_ostream.h"
      14             : #include <cassert>
      15             : #include <vector>
      16             : using namespace llvm;
      17             : 
      18             : // Clients are responsible for avoid race conditions in registration.
      19             : static Target *FirstTarget = nullptr;
      20             : 
      21      174370 : iterator_range<TargetRegistry::iterator> TargetRegistry::targets() {
      22      348740 :   return make_range(iterator(FirstTarget), iterator());
      23             : }
      24             : 
      25       24994 : const Target *TargetRegistry::lookupTarget(const std::string &ArchName,
      26             :                                            Triple &TheTriple,
      27             :                                            std::string &Error) {
      28             :   // Allocate target machine.  First, check whether the user has explicitly
      29             :   // specified an architecture to compile for. If so we have to look it up by
      30             :   // name, because it might be a backend that has no mapping to a target triple.
      31       24994 :   const Target *TheTarget = nullptr;
      32       24994 :   if (!ArchName.empty()) {
      33        9498 :     auto I = find_if(targets(),
      34      192298 :                      [&](const Target &T) { return ArchName == T.getName(); });
      35             : 
      36        4749 :     if (I == targets().end()) {
      37           9 :       Error = "error: invalid target '" + ArchName + "'.\n";
      38           3 :       return nullptr;
      39             :     }
      40             : 
      41        4746 :     TheTarget = &*I;
      42             : 
      43             :     // Adjust the triple to match (if known), otherwise stick with the
      44             :     // given triple.
      45        4746 :     Triple::ArchType Type = Triple::getArchTypeForLLVMName(ArchName);
      46        4746 :     if (Type != Triple::UnknownArch)
      47        4746 :       TheTriple.setArch(Type);
      48             :   } else {
      49             :     // Get the target specific parser.
      50       40476 :     std::string TempError;
      51       20245 :     TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), TempError);
      52       20245 :     if (!TheTarget) {
      53          14 :       Error = ": error: unable to get target for '"
      54          28 :             + TheTriple.getTriple()
      55          28 :             + "', see --version and --triple.\n";
      56          28 :       return nullptr;
      57             :     }
      58             :   }
      59             : 
      60             :   return TheTarget;
      61             : }
      62             : 
      63       27539 : const Target *TargetRegistry::lookupTarget(const std::string &TT,
      64             :                                            std::string &Error) {
      65             :   // Provide special warning when no targets are initialized.
      66       27539 :   if (targets().begin() == targets().end()) {
      67          33 :     Error = "Unable to find target for this triple (no targets are registered)";
      68          33 :     return nullptr;
      69             :   }
      70       55012 :   Triple::ArchType Arch = Triple(TT).getArch();
      71      873254 :   auto ArchMatch = [&](const Target &T) { return T.ArchMatchFn(Arch); };
      72       55011 :   auto I = find_if(targets(), ArchMatch);
      73             : 
      74       27505 :   if (I == targets().end()) {
      75         116 :     Error = "No available targets are compatible with this triple.";
      76         116 :     return nullptr;
      77             :   }
      78             : 
      79       54779 :   auto J = std::find_if(std::next(I), targets().end(), ArchMatch);
      80       54779 :   if (J != targets().end()) {
      81           0 :     Error = std::string("Cannot choose between targets \"") + I->Name +
      82           0 :             "\" and \"" + J->Name + "\"";
      83           0 :     return nullptr;
      84             :   }
      85             : 
      86             :   return &*I;
      87             : }
      88             : 
      89     2437604 : void TargetRegistry::RegisterTarget(Target &T,
      90             :                                     const char *Name,
      91             :                                     const char *ShortDesc,
      92             :                                     Target::ArchMatchFnTy ArchMatchFn,
      93             :                                     bool HasJIT) {
      94             :   assert(Name && ShortDesc && ArchMatchFn &&
      95             :          "Missing required target information!");
      96             : 
      97             :   // Check if this target has already been initialized, we allow this as a
      98             :   // convenience to some clients.
      99     2437604 :   if (T.Name)
     100             :     return;
     101             :          
     102             :   // Add to the list of targets.
     103     1872071 :   T.Next = FirstTarget;
     104     1872071 :   FirstTarget = &T;
     105             : 
     106     1872071 :   T.Name = Name;
     107     1872071 :   T.ShortDesc = ShortDesc;
     108     1872071 :   T.ArchMatchFn = ArchMatchFn;
     109     1872071 :   T.HasJIT = HasJIT;
     110             : }
     111             : 
     112           0 : static int TargetArraySortFn(const std::pair<StringRef, const Target *> *LHS,
     113             :                              const std::pair<StringRef, const Target *> *RHS) {
     114           0 :   return LHS->first.compare(RHS->first);
     115             : }
     116             : 
     117           0 : void TargetRegistry::printRegisteredTargetsForVersion(raw_ostream &OS) {
     118           0 :   std::vector<std::pair<StringRef, const Target*> > Targets;
     119           0 :   size_t Width = 0;
     120           0 :   for (const auto &T : TargetRegistry::targets()) {
     121           0 :     Targets.push_back(std::make_pair(T.getName(), &T));
     122           0 :     Width = std::max(Width, Targets.back().first.size());
     123             :   }
     124           0 :   array_pod_sort(Targets.begin(), Targets.end(), TargetArraySortFn);
     125             : 
     126           0 :   OS << "  Registered Targets:\n";
     127           0 :   for (unsigned i = 0, e = Targets.size(); i != e; ++i) {
     128           0 :     OS << "    " << Targets[i].first;
     129           0 :     OS.indent(Width - Targets[i].first.size()) << " - "
     130           0 :       << Targets[i].second->getShortDescription() << '\n';
     131             :   }
     132           0 :   if (Targets.empty())
     133           0 :     OS << "    (none)\n";
     134           0 : }

Generated by: LCOV version 1.13